<commit_before>//! A set of builders to generate Rust source for PHF data structures at
//! compile time.
//!
//! The provided builders are intended to be used in a Cargo build script to
//! generate a Rust source file that will be included in a library at build
//! time.
//!
//! # Examples
//!
//! build.rs
//!
//! ```rust,no_run
//! extern crate phf_codegen;
//!
//! use std::fs::File;
//! use std::io::{BufWriter, Write};
//! use std::path::AsPath;
//! use std::env;
//!
//! fn main() {
//!     let path = env::var_os("OUT_DIR").unwrap().as_path().join("codegen.rs");
//!     let mut file = BufWriter::new(File::create(&path).unwrap());
//!
//!     write!(&mut file, "static KEYWORDS: phf::Map<&'static str, Keyword> = ").unwrap();
//!     phf_codegen::Map::new()
//!         .entry("loop", "Keyword::Loop")
//!         .entry("continue", "Keyword::Continue")
//!         .entry("break", "Keyword::Break")
//!         .entry("fn", "Keyword::Fn")
//!         .entry("extern", "Keyword::Extern")
//!         .build(&mut file)
//!         .unwrap();
//!     write!(&mut file, ";\n").unwrap();
//! }
//! ```
//!
//! lib.rs
//!
//! ```ignore
//! extern crate phf;
//!
//! #[derive(Clone)]
//! enum Keyword {
//!     Loop,
//!     Continue,
//!     Break,
//!     Fn,
//!     Extern,
//! }
//!
//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
//!
//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
//!     KEYWORDS.get(keyword).cloned()
//! }
//! ```
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]
#![feature(io)]

extern crate phf_shared;
extern crate phf_generator;

use phf_shared::PhfHash;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::io;
use std::io::prelude::*;

/// A builder for the `phf::Map` type.
pub struct Map<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> Map<K> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::Map`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::Map {{ key: {}, disps: &[", state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "({}, {}),", d1, d2));
        }
        try!(write!(w, "], entries: &["));
        for &idx in &state.map {
            try!(write!(w, "({:?}, {}),", &self.keys[idx], &self.values[idx]));
        }
        write!(w, "] }}")
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set {
            map: Map::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::Set`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::Set {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> OrderedMap<K> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::OrderedMap`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::OrderedMap {{ key: {}, disps: &[", state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "({}, {}),", d1, d2));
        }
        try!(write!(w, "], idxs: &["));
        for &idx in &state.map {
            try!(write!(w, "{},", idx));
        }
        try!(write!(w, "], entries: &["));
        for (key, value) in self.keys.iter().zip(self.values.iter()) {
            try!(write!(w, "({:?}, {}),", key, value));
        }
        write!(w, "] }}")
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet {
            map: OrderedMap::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::OrderedSet`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::OrderedSet {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}
<commit_msg>Pretty print generated structs<commit_after>//! A set of builders to generate Rust source for PHF data structures at
//! compile time.
//!
//! The provided builders are intended to be used in a Cargo build script to
//! generate a Rust source file that will be included in a library at build
//! time.
//!
//! # Examples
//!
//! build.rs
//!
//! ```rust,no_run
//! extern crate phf_codegen;
//!
//! use std::fs::File;
//! use std::io::{BufWriter, Write};
//! use std::path::AsPath;
//! use std::env;
//!
//! fn main() {
//!     let path = env::var_os("OUT_DIR").unwrap().as_path().join("codegen.rs");
//!     let mut file = BufWriter::new(File::create(&path).unwrap());
//!
//!     write!(&mut file, "static KEYWORDS: phf::Map<&'static str, Keyword> = ").unwrap();
//!     phf_codegen::Map::new()
//!         .entry("loop", "Keyword::Loop")
//!         .entry("continue", "Keyword::Continue")
//!         .entry("break", "Keyword::Break")
//!         .entry("fn", "Keyword::Fn")
//!         .entry("extern", "Keyword::Extern")
//!         .build(&mut file)
//!         .unwrap();
//!     write!(&mut file, ";\n").unwrap();
//! }
//! ```
//!
//! lib.rs
//!
//! ```ignore
//! extern crate phf;
//!
//! #[derive(Clone)]
//! enum Keyword {
//!     Loop,
//!     Continue,
//!     Break,
//!     Fn,
//!     Extern,
//! }
//!
//! include!(concat!(env!("OUT_DIR"), "/codegen.rs"));
//!
//! pub fn parse_keyword(keyword: &str) -> Option<Keyword> {
//!     KEYWORDS.get(keyword).cloned()
//! }
//! ```
#![doc(html_root_url="http://sfackler.github.io/rust-phf/doc")]
#![feature(io)]

extern crate phf_shared;
extern crate phf_generator;

use phf_shared::PhfHash;
use std::collections::HashSet;
use std::fmt;
use std::hash::Hash;
use std::io;
use std::io::prelude::*;

/// A builder for the `phf::Map` type.
pub struct Map<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> Map<K> {
    /// Creates a new `phf::Map` builder.
    pub fn new() -> Map<K> {
        Map {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut Map<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::Map`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::Map {{
    key: {},
    disps: &[
",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    entries: &[
"));
        for &idx in &state.map {
            try!(write!(w, "
        ({:?}, {}),",
                        &self.keys[idx], &self.values[idx]));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::Set` type.
pub struct Set<T> {
    map: Map<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> Set<T> {
    /// Constructs a new `phf::Set` builder.
    pub fn new() -> Set<T> {
        Set {
            map: Map::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut Set<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::Set`, outputting Rust source to the provided writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::Set {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}

/// A builder for the `phf::OrderedMap` type.
pub struct OrderedMap<K> {
    keys: Vec<K>,
    values: Vec<String>,
}

impl<K: Hash+PhfHash+Eq+fmt::Debug> OrderedMap<K> {
    /// Constructs a enw `phf::OrderedMap` builder.
    pub fn new() -> OrderedMap<K> {
        OrderedMap {
            keys: vec![],
            values: vec![],
        }
    }

    /// Adds an entry to the builder.
    ///
    /// `value` will be written exactly as provided in the constructed source.
    pub fn entry(&mut self, key: K, value: &str) -> &mut OrderedMap<K> {
        self.keys.push(key);
        self.values.push(value.to_string());
        self
    }

    /// Constructs a `phf::OrderedMap`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate keys.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        let mut set = HashSet::new();
        for key in &self.keys {
            if !set.insert(key) {
                panic!("duplicate key `{:?}`", key);
            }
        }

        let state = phf_generator::generate_hash(&self.keys);

        try!(write!(w, "::phf::OrderedMap {{
    key: {},
    disps: &[",
                    state.key));
        for &(d1, d2) in &state.disps {
            try!(write!(w, "
        ({}, {}),",
                        d1, d2));
        }
        try!(write!(w, "
    ],
    idxs: &["));
        for &idx in &state.map {
            try!(write!(w, "
        {},",
                        idx));
        }
        try!(write!(w, "
    ],
    entries: &["));
        for (key, value) in self.keys.iter().zip(self.values.iter()) {
            try!(write!(w, "
        ({:?}, {}),",
                        key, value));
        }
        write!(w, "
    ]
}}")
    }
}

/// A builder for the `phf::OrderedSet` type.
pub struct OrderedSet<T> {
    map: OrderedMap<T>
}

impl<T: Hash+PhfHash+Eq+fmt::Debug> OrderedSet<T> {
    /// Constructs a new `phf::OrderedSet` builder.
    pub fn new() -> OrderedSet<T> {
        OrderedSet {
            map: OrderedMap::new()
        }
    }

    /// Adds an entry to the builder.
    pub fn entry(&mut self, entry: T) -> &mut OrderedSet<T> {
        self.map.entry(entry, "()");
        self
    }

    /// Constructs a `phf::OrderedSet`, outputting Rust source to the provided
    /// writer.
    ///
    /// # Panics
    ///
    /// Panics if there are any duplicate entries.
    pub fn build<W: Write>(&self, w: &mut W) -> io::Result<()> {
        try!(write!(w, "::phf::OrderedSet {{ map: "));
        try!(self.map.build(w));
        write!(w, " }}")
    }
}
<|endoftext|>


<commit_before><commit_msg>abstract into Analyzer struct<commit_after><|endoftext|>


<commit_before>//! Arena allocator inspired by LuaJIT's [new GC](http://wiki.luajit.org/New-Garbage-Collector).
//!
//! The allocator uses fixed-size arenas to allocate all objects. An arena can have any power-of-two
//! size from 64 KiB up to 1 MiB. Arenas are split up into 16 Byte cells. 1/64th of the arena is
//! reserved for metadata. Arenas must be aligned to their size, which requires platform-specific
//! allocation code (there seems to be no suitable "aligned allocation" crate).

// TODO: Evaluate the use of huge pages for arena allocation (on each OS separately). Might want to
// switch dynamically, to prevent too much wasted memory (does this really matter?).

mod box64;

use GcStrategy;
use GcCallback;
use string::Str;
use TracedRef;

use aligned_alloc::{aligned_alloc, aligned_free};

use std::any::Any;
use std::cmp;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::u16;

/// Selects the size of an arena:
///
/// * 0 = 64 KiB
/// * 1 = 128 KiB
/// * 2 = 256 KiB
/// * 3 = 512 KiB
/// * 4 = 1 MiB
const ARENA_SIZE_CLASS: usize = 4;

/// Size of each arena in bytes
const ARENA_SIZE: usize = 1 << (16 + ARENA_SIZE_CLASS);
/// Size of the metadata area (always 1/64th of the arena size)
const METADATA_SIZE: usize = ARENA_SIZE / 64;
/// Size of the data area in an arena (area available for allocation) (in Bytes)
const DATA_SIZE: usize = ARENA_SIZE - METADATA_SIZE;

/// Number of cells in the data area.
///
/// There are at most 64512 cells when using 1 MiB arenas, so a cell number always fits in 16 bits.
const CELL_COUNT: u16 = (DATA_SIZE / 16) as u16;

/// First valid cell index / size of metadata in cells.
///
/// This is also the number of unused bits at the start of the bitmaps.
const FIRST_CELL_INDEX: u16 = (METADATA_SIZE / 16) as u16;

/// Number of unused bytes at the start of the bitmaps. Two times this is the number of unused Bytes
/// in the arena metadata.
const UNUSED_BITMAP_BYTES: usize = (FIRST_CELL_INDEX / 8) as usize;

/// Size of the bitmaps in bytes
const BITMAP_SIZE: usize = CELL_COUNT as usize / 8;

type Cell = [u8; 16];

#[repr(C)]
struct Bitmap([u8; BITMAP_SIZE]);

impl Bitmap {
    fn get_bit(&self, bit: u16) -> bool {
        let byte_index = bit / 8;
        let bit_off = bit % 8;
        let byte = self.0[byte_index as usize];

        byte & (1 << bit_off) != 0
    }

    fn get(&self, cell: u16) -> bool {
        self.get_bit(cell - FIRST_CELL_INDEX)
    }

    fn set_bit(&mut self, bit: u16, value: bool) {
        let byte_index = bit / 8;
        let bit_off = bit % 8;
        let byte = &mut self.0[byte_index as usize];

        match value {
            true  => *byte |= 1 << bit_off,
            false => *byte &= !(1 << bit_off),
        }
    }

    fn set(&mut self, cell: u16, value: bool) {
        self.set_bit(cell - FIRST_CELL_INDEX, value)
    }
}

/// The metadata section of an arena contains 2 bitmaps, storing block and mark bits for each cell.
#[repr(C)]
struct Metadata {
    unused_0: [u8; UNUSED_BITMAP_BYTES],
    block_bitmap: Bitmap,
    unused_1: [u8; UNUSED_BITMAP_BYTES],
    mark_bitmap: Bitmap,
}

impl Default for Metadata {
    fn default() -> Self {
        let mut this = Metadata {
            unused_0: [0; UNUSED_BITMAP_BYTES],
            block_bitmap: Bitmap([0; BITMAP_SIZE]),
            unused_1: [0; UNUSED_BITMAP_BYTES],
            mark_bitmap: Bitmap([0; BITMAP_SIZE]),
        };

        // Mark the first block as free. This marks the entire arena as free.
        this.mark_bitmap.set(FIRST_CELL_INDEX, true);

        this
    }
}

/// An arena. This structure is large, never handle it by-value, only via `ArenaBox`.
#[repr(C)]
struct Arena {
    metadata: Metadata,
    cells: [Cell; CELL_COUNT as usize],
}

impl Arena {
    /// Allocates a new `Arena` and returns an `ArenaBox`.
    fn new() -> ArenaBox {
        // `alloc_arena` returns uninitialized memory. The arena doesn't care if the data area is
        // uninitialized, but the metadata area needs to be cleared first.
        unsafe {
            let mut b = ArenaBox::alloc();
            b.metadata = Metadata::default();

            b
        }
    }

    fn cell_index_to_ptr(&self, cell: u16) -> *mut () {
        let self_ptr = self as *const _ as usize;
        let cell_addr = self_ptr + ((cell as usize) << 4);

        cell_addr as *mut ()
    }

    /// Tries to allocate `cells` Cells inside this arena. Return the allocated cell index on
    /// success and `None` on failure.
    fn alloc_cells(&mut self, cells: u16) -> Option<u16> {
        debug_assert!(cells > 0);

        // Find a free block (first cell has: Block = 0, Mark = 1) that's large enough

        // First index of current free block
        let mut block_start = None;
        // Length of our current free block
        let mut block_len = 0;

        for cell in FIRST_CELL_INDEX..CELL_COUNT {
            let block = self.metadata.block_bitmap.get(cell);
            let mark = self.metadata.mark_bitmap.get(cell);

            if block_start.is_none() {
                // We don't have a free block we can follow, so we're only interested in new free
                // blocks.
                if !block && mark {
                    // Start of a free block. Save the index.
                    block_start = Some(cell);
                    block_len = 0;
                }
            } else {
                match (block, mark) {
                    (false, false) => {
                        // Block extent
                        block_len += 1;
                    }
                    (false, true) => {
                        // New free block. Coalesce with our current free block, since they're
                        // adjacent.
                        self.metadata.mark_bitmap.set(cell, false); // Make cell block extent
                        block_len += 1;
                    }
                    (true, _) => {
                        // Start of allocated block. Since our block is too small for the
                        // allocation, we have to start over.
                        block_start = None;
                    }
                }

                if block_len == cells {
                    // Done, cut the block into pieces and allocate. `cell` is the last cell of the
                    // allocated block.

                    let block_start = block_start.unwrap();

                    // Mark the block as allocated:
                    self.metadata.block_bitmap.set(block_start, true);

                    // Mark the following cell as a new free block, if applicable
                    if cell < CELL_COUNT {
                        let block = self.metadata.block_bitmap.get(cell + 1);
                        let mark = self.metadata.mark_bitmap.get(cell + 1);
                        if !block && !mark {
                            // Block extent. Make new free block.
                            self.metadata.mark_bitmap.set(cell + 1, true);
                        }
                    }

                    return Some(block_start)
                }
            }
        }

        None
    }

    /// Tries to allocate `size` bytes inside this arena. The allocation will always be aligned to
    /// 16 bytes.
    fn alloc(&mut self, size: usize) -> Option<*mut ()> {
        let cells = cmp::max(1, size.next_power_of_two());
        debug_assert!(cells <= u16::MAX as usize);

        self.alloc_cells(cells as u16).map(|cell| self.cell_index_to_ptr(cell))
    }
}

/// Manages an `Arena`, allocated with a suitable alignment.
struct ArenaBox(*mut Arena);

impl ArenaBox {
    /// Allocates an uninitialized `Arena`
    unsafe fn alloc() -> ArenaBox {
        ArenaBox(aligned_alloc(ARENA_SIZE, ARENA_SIZE) as *mut Arena)
    }
}

impl Deref for ArenaBox {
    type Target = Arena;
    fn deref(&self) -> &Arena { unsafe { &*self.0 } }
}

impl DerefMut for ArenaBox {
    fn deref_mut(&mut self) -> &mut Arena { unsafe { &mut *self.0 } }
}

impl Drop for ArenaBox {
    fn drop(&mut self) {
        unsafe { aligned_free(self.0 as *mut ()) }
    }
}

/// Arena-based GC
pub struct ArenaGc {
    arenas: Vec<ArenaBox>,
}

impl GcStrategy for ArenaGc {
    fn collect_step<C: GcCallback>(&mut self, cb: &mut C) {
        // TODO Make this incremental
        self.collect_atomic(cb)
    }

    fn collect_atomic<C: GcCallback>(&mut self, _cb: &mut C) { unimplemented!(); }

    fn register_obj<T: Any>(&mut self, _obj: T) -> TracedRef<T> {
        // FIXME: Don't traverse arenas for allocation
        // FIXME: Implement a less naive algorithm for allocation (see LuaJIT wiki)
        // FIXME: Allow higher alignment (or not, depends)
        // FIXME: Allocate large objects in segregated area (or not, we don't really use it)

        let size = mem::size_of::<T>();

        debug_assert!(mem::align_of::<T>() <= 16,
            "align {} too large for arena allocation", mem::align_of::<T>());
        debug_assert!(size <= 64, "size {} too large for arena allocation", size);

        for arena in &mut self.arenas {
            if let Some(ptr) = arena.alloc(size) {
                return TracedRef {
                    ptr: ptr as *const T,
                }
            }
        }

        // no luck, allocate a new arena
        let mut arena = Arena::new();
        let traced_ref = match arena.alloc(size) {
            Some(ptr) => TracedRef {
                ptr: ptr as *const T,
            },
            None => panic!("empty arena couldn't allocate {} bytes", size)
        };

        self.arenas.push(arena);
        traced_ref
    }

    fn intern_str<T: Into<Str>>(&mut self, _s: T) -> TracedRef<Str> { unimplemented!(); }
}

/// Makes sure that the selected arena size is valid
#[test]
fn arena_size() {
    assert!(ARENA_SIZE.is_power_of_two(), "arena size {} not a power of 2", ARENA_SIZE);
    assert!(ARENA_SIZE >= 64 * 1024, "arena size {} smaller than 64 KiB", ARENA_SIZE);
    assert!(ARENA_SIZE <= 1024 * 1024, "arena size {} larger than 1 MiB", ARENA_SIZE);
}

/// Makes sure that all constants have sane values
#[test]
fn consts() {
    assert!(FIRST_CELL_INDEX >= 1024 / 16,
        "first valid cell index is {}", FIRST_CELL_INDEX);
    assert!(METADATA_SIZE >= 1024,
        "metadata size ({} Bytes) too small", METADATA_SIZE);
    assert!(UNUSED_BITMAP_BYTES >= 8,
        "unused metadata bytes: {}", UNUSED_BITMAP_BYTES);
    assert_eq!(METADATA_SIZE % 16, 0);
    assert_eq!(METADATA_SIZE * 64, ARENA_SIZE);
    assert_eq!(CELL_COUNT as usize * 16, DATA_SIZE);
}

#[test]
fn struct_size() {
    use std::mem::size_of;

    assert_eq!(size_of::<Arena>(), ARENA_SIZE);
    assert_eq!(size_of::<Metadata>(), METADATA_SIZE);
}

#[test]
fn bitmaps() {
    let mut bm = Bitmap([0; BITMAP_SIZE]);
    assert_eq!(bm.get_bit(0), false);
    assert_eq!(bm.get_bit(1), false);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(0, true);
    assert_eq!(bm.get_bit(0), true);
    assert_eq!(bm.get_bit(1), false);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(1, true);
    assert_eq!(bm.get_bit(0), true);
    assert_eq!(bm.get_bit(1), true);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(0, false);
    assert_eq!(bm.get_bit(0), false);
    assert_eq!(bm.get_bit(1), true);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(1, false);
    assert_eq!(bm.get_bit(1), false);
    bm.set_bit(BITMAP_SIZE as u16 - 1, true);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), true);
}

#[test]
fn alloc() {
    let mut arena = Arena::new();
    assert_eq!(arena.metadata.mark_bitmap.get(FIRST_CELL_INDEX), true);
    assert_eq!(arena.metadata.block_bitmap.get(FIRST_CELL_INDEX), false);
    assert_eq!(arena.alloc_cells(1), Some(FIRST_CELL_INDEX));
}
<commit_msg>arena: fix allocation<commit_after>//! Arena allocator inspired by LuaJIT's [new GC](http://wiki.luajit.org/New-Garbage-Collector).
//!
//! The allocator uses fixed-size arenas to allocate all objects. An arena can have any power-of-two
//! size from 64 KiB up to 1 MiB. Arenas are split up into 16 Byte cells. 1/64th of the arena is
//! reserved for metadata. Arenas must be aligned to their size, which requires platform-specific
//! allocation code (there seems to be no suitable "aligned allocation" crate).

// TODO: Evaluate the use of huge pages for arena allocation (on each OS separately). Might want to
// switch dynamically, to prevent too much wasted memory (does this really matter?).

mod box64;

use GcStrategy;
use GcCallback;
use string::Str;
use TracedRef;

use aligned_alloc::{aligned_alloc, aligned_free};

use std::any::Any;
use std::cmp;
use std::mem;
use std::ops::{Deref, DerefMut};
use std::u16;

/// Selects the size of an arena:
///
/// * 0 = 64 KiB
/// * 1 = 128 KiB
/// * 2 = 256 KiB
/// * 3 = 512 KiB
/// * 4 = 1 MiB
const ARENA_SIZE_CLASS: usize = 4;

/// Size of each arena in bytes
const ARENA_SIZE: usize = 1 << (16 + ARENA_SIZE_CLASS);
/// Size of the metadata area (always 1/64th of the arena size)
const METADATA_SIZE: usize = ARENA_SIZE / 64;
/// Size of the data area in an arena (area available for allocation) (in Bytes)
const DATA_SIZE: usize = ARENA_SIZE - METADATA_SIZE;

/// Number of cells in the data area.
///
/// There are at most 64512 cells when using 1 MiB arenas, so a cell number always fits in 16 bits.
const CELL_COUNT: u16 = (DATA_SIZE / 16) as u16;

/// First valid cell index / size of metadata in cells.
///
/// This is also the number of unused bits at the start of the bitmaps.
const FIRST_CELL_INDEX: u16 = (METADATA_SIZE / 16) as u16;

/// Number of unused bytes at the start of the bitmaps. Two times this is the number of unused Bytes
/// in the arena metadata.
const UNUSED_BITMAP_BYTES: usize = (FIRST_CELL_INDEX / 8) as usize;

/// Size of the bitmaps in bytes
const BITMAP_SIZE: usize = CELL_COUNT as usize / 8;

type Cell = [u8; 16];

#[repr(C)]
struct Bitmap([u8; BITMAP_SIZE]);

impl Bitmap {
    fn get_bit(&self, bit: u16) -> bool {
        let byte_index = bit / 8;
        let bit_off = bit % 8;
        let byte = self.0[byte_index as usize];

        byte & (1 << bit_off) != 0
    }

    fn get(&self, cell: u16) -> bool {
        self.get_bit(cell - FIRST_CELL_INDEX)
    }

    fn set_bit(&mut self, bit: u16, value: bool) {
        let byte_index = bit / 8;
        let bit_off = bit % 8;
        let byte = &mut self.0[byte_index as usize];

        match value {
            true  => *byte |= 1 << bit_off,
            false => *byte &= !(1 << bit_off),
        }
    }

    fn set(&mut self, cell: u16, value: bool) {
        self.set_bit(cell - FIRST_CELL_INDEX, value)
    }
}

/// The metadata section of an arena contains 2 bitmaps, storing block and mark bits for each cell.
#[repr(C)]
struct Metadata {
    unused_0: [u8; UNUSED_BITMAP_BYTES],
    block_bitmap: Bitmap,
    unused_1: [u8; UNUSED_BITMAP_BYTES],
    mark_bitmap: Bitmap,
}

impl Default for Metadata {
    fn default() -> Self {
        let mut this = Metadata {
            unused_0: [0; UNUSED_BITMAP_BYTES],
            block_bitmap: Bitmap([0; BITMAP_SIZE]),
            unused_1: [0; UNUSED_BITMAP_BYTES],
            mark_bitmap: Bitmap([0; BITMAP_SIZE]),
        };

        // Mark the first block as free. This marks the entire arena as free.
        this.mark_bitmap.set(FIRST_CELL_INDEX, true);

        this
    }
}

/// An arena. This structure is large, never handle it by-value, only via `ArenaBox`.
#[repr(C)]
struct Arena {
    metadata: Metadata,
    cells: [Cell; CELL_COUNT as usize],
}

impl Arena {
    /// Allocates a new `Arena` and returns an `ArenaBox`.
    fn new() -> ArenaBox {
        // `alloc_arena` returns uninitialized memory. The arena doesn't care if the data area is
        // uninitialized, but the metadata area needs to be cleared first.
        unsafe {
            let mut b = ArenaBox::alloc();
            b.metadata = Metadata::default();

            b
        }
    }

    fn cell_index_to_ptr(&self, cell: u16) -> *mut () {
        let self_ptr = self as *const _ as usize;
        let cell_addr = self_ptr + ((cell as usize) << 4);

        cell_addr as *mut ()
    }

    /// Tries to allocate `cells` Cells inside this arena. Return the allocated cell index on
    /// success and `None` on failure.
    fn alloc_cells(&mut self, cells: u16) -> Option<u16> {
        debug_assert!(cells > 0);

        // Find a free block (first cell has: Block = 0, Mark = 1) that's large enough

        // First index of current free block
        let mut block_start = 0;
        // Length of our current free block. If 0, no current free block exists.
        let mut block_len = 0;

        for cell in FIRST_CELL_INDEX..CELL_COUNT {
            let block = self.metadata.block_bitmap.get(cell);
            let mark = self.metadata.mark_bitmap.get(cell);

            if block_len == 0 {
                // We don't have a free block we can follow, so we're only interested in new free
                // blocks.
                if !block && mark {
                    // Start of a free block. Save the index.
                    block_start = cell;
                    block_len = 1;
                }
            } else {
                match (block, mark) {
                    (false, false) => {
                        // Block extent
                        block_len += 1;
                    }
                    (false, true) => {
                        // New free block. Coalesce with our current free block, since they're
                        // adjacent.
                        self.metadata.mark_bitmap.set(cell, false); // Make cell block extent
                        block_len += 1;
                    }
                    (true, _) => {
                        // Start of allocated block. Since our block is too small for the
                        // allocation, we have to start over.
                        block_len = 0;
                        continue;
                    }
                }
            }

            if block_len == cells {
                // Done, cut the block into pieces and allocate. `cell` is the last cell of the
                // allocated block.

                // Mark the block as allocated:
                self.metadata.block_bitmap.set(block_start, true);

                // Mark the following cell as a new free block, if applicable
                if cell < CELL_COUNT {
                    let block = self.metadata.block_bitmap.get(cell + 1);
                    let mark = self.metadata.mark_bitmap.get(cell + 1);
                    if !block && !mark {
                        // Block extent. Make new free block.
                        self.metadata.mark_bitmap.set(cell + 1, true);
                    }
                }

                return Some(block_start)
            }
        }

        None
    }

    /// Tries to allocate `size` bytes inside this arena. The allocation will always be aligned to
    /// 16 bytes.
    fn alloc(&mut self, size: usize) -> Option<*mut ()> {
        let cells = cmp::max(1, size.next_power_of_two());
        debug_assert!(cells <= u16::MAX as usize);

        self.alloc_cells(cells as u16).map(|cell| self.cell_index_to_ptr(cell))
    }
}

/// Manages an `Arena`, allocated with a suitable alignment.
struct ArenaBox(*mut Arena);

impl ArenaBox {
    /// Allocates an uninitialized `Arena`
    unsafe fn alloc() -> ArenaBox {
        ArenaBox(aligned_alloc(ARENA_SIZE, ARENA_SIZE) as *mut Arena)
    }
}

impl Deref for ArenaBox {
    type Target = Arena;
    fn deref(&self) -> &Arena { unsafe { &*self.0 } }
}

impl DerefMut for ArenaBox {
    fn deref_mut(&mut self) -> &mut Arena { unsafe { &mut *self.0 } }
}

impl Drop for ArenaBox {
    fn drop(&mut self) {
        unsafe { aligned_free(self.0 as *mut ()) }
    }
}

/// Arena-based GC
pub struct ArenaGc {
    arenas: Vec<ArenaBox>,
}

impl GcStrategy for ArenaGc {
    fn collect_step<C: GcCallback>(&mut self, cb: &mut C) {
        // TODO Make this incremental
        self.collect_atomic(cb)
    }

    fn collect_atomic<C: GcCallback>(&mut self, _cb: &mut C) { unimplemented!(); }

    fn register_obj<T: Any>(&mut self, _obj: T) -> TracedRef<T> {
        // FIXME: Don't traverse arenas for allocation
        // FIXME: Implement a less naive algorithm for allocation (see LuaJIT wiki)
        // FIXME: Allow higher alignment (or not, depends)
        // FIXME: Allocate large objects in segregated area (or not, we don't really use it)

        let size = mem::size_of::<T>();

        debug_assert!(mem::align_of::<T>() <= 16,
            "align {} too large for arena allocation", mem::align_of::<T>());
        debug_assert!(size <= 64, "size {} too large for arena allocation", size);

        for arena in &mut self.arenas {
            if let Some(ptr) = arena.alloc(size) {
                return TracedRef {
                    ptr: ptr as *const T,
                }
            }
        }

        // no luck, allocate a new arena
        let mut arena = Arena::new();
        let traced_ref = match arena.alloc(size) {
            Some(ptr) => TracedRef {
                ptr: ptr as *const T,
            },
            None => panic!("empty arena couldn't allocate {} bytes", size)
        };

        self.arenas.push(arena);
        traced_ref
    }

    fn intern_str<T: Into<Str>>(&mut self, _s: T) -> TracedRef<Str> { unimplemented!(); }
}

/// Makes sure that the selected arena size is valid
#[test]
fn arena_size() {
    assert!(ARENA_SIZE.is_power_of_two(), "arena size {} not a power of 2", ARENA_SIZE);
    assert!(ARENA_SIZE >= 64 * 1024, "arena size {} smaller than 64 KiB", ARENA_SIZE);
    assert!(ARENA_SIZE <= 1024 * 1024, "arena size {} larger than 1 MiB", ARENA_SIZE);
}

/// Makes sure that all constants have sane values
#[test]
fn consts() {
    assert!(FIRST_CELL_INDEX >= 1024 / 16,
        "first valid cell index is {}", FIRST_CELL_INDEX);
    assert!(METADATA_SIZE >= 1024,
        "metadata size ({} Bytes) too small", METADATA_SIZE);
    assert!(UNUSED_BITMAP_BYTES >= 8,
        "unused metadata bytes: {}", UNUSED_BITMAP_BYTES);
    assert_eq!(METADATA_SIZE % 16, 0);
    assert_eq!(METADATA_SIZE * 64, ARENA_SIZE);
    assert_eq!(CELL_COUNT as usize * 16, DATA_SIZE);
}

#[test]
fn struct_size() {
    use std::mem::size_of;

    assert_eq!(size_of::<Arena>(), ARENA_SIZE);
    assert_eq!(size_of::<Metadata>(), METADATA_SIZE);
}

#[test]
fn bitmaps() {
    let mut bm = Bitmap([0; BITMAP_SIZE]);
    assert_eq!(bm.get_bit(0), false);
    assert_eq!(bm.get_bit(1), false);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(0, true);
    assert_eq!(bm.get_bit(0), true);
    assert_eq!(bm.get_bit(1), false);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(1, true);
    assert_eq!(bm.get_bit(0), true);
    assert_eq!(bm.get_bit(1), true);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(0, false);
    assert_eq!(bm.get_bit(0), false);
    assert_eq!(bm.get_bit(1), true);
    assert_eq!(bm.get_bit(2), false);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), false);
    bm.set_bit(1, false);
    assert_eq!(bm.get_bit(1), false);
    bm.set_bit(BITMAP_SIZE as u16 - 1, true);
    assert_eq!(bm.get_bit(BITMAP_SIZE as u16 - 1), true);
}

#[test]
fn alloc() {
    let mut arena = Arena::new();
    assert_eq!(arena.metadata.mark_bitmap.get(FIRST_CELL_INDEX), true);
    assert_eq!(arena.metadata.block_bitmap.get(FIRST_CELL_INDEX), false);
    assert_eq!(arena.alloc_cells(1), Some(FIRST_CELL_INDEX));
    assert_eq!(arena.alloc_cells(17), Some(FIRST_CELL_INDEX + 1));
    assert_eq!(arena.alloc_cells(1), Some(FIRST_CELL_INDEX + 1 + 17));
}
<|endoftext|>


<commit_before>//! # Synchronizing Widgets
//!
//! You can use signals in order to synchronize the values of widgets. In this example a spin button and a horizontal scale will get interlocked.

#![crate_type = "bin"]

extern crate rgtk;

use rgtk::*;
use rgtk::gtk::signals::{ValueChanged, DeleteEvent};

fn main() {
    gtk::init();

    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();

    window.set_title("Enter your age");
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(300, 20);

    let mut spin_button = gtk::SpinButton::new_with_range(0.0, 130.0, 1.0).unwrap();
    let slider = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0.0, 130.0, 1.0).unwrap();

    Connect::connect(&spin_button, ValueChanged::new(&mut |&:| {
        let mut adjustment = slider.get_adjustment();

        adjustment.set_value(spin_button.get_value());
    }));

    Connect::connect(&slider, ValueChanged::new(&mut |_| {
        let adjustment = slider.get_adjustment();

        spin_button.set_value(adjustment.get_value());
    }));

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 5).unwrap();

    hbox.set_homogeneouse(true);
    hbox.add(&spin_button);
    hbox.add(&slider);

    Connect::connect(&window, DeleteEvent::new(&mut |_| {
        gtk::main_quit();
        true
    }));

    window.add(&hbox);
    window.show_all();
    gtk::main();
}<commit_msg>Fix invalid closure<commit_after>//! # Synchronizing Widgets
//!
//! You can use signals in order to synchronize the values of widgets. In this example a spin button and a horizontal scale will get interlocked.

#![crate_type = "bin"]

extern crate rgtk;

use rgtk::*;
use rgtk::gtk::signals::{ValueChanged, DeleteEvent};

fn main() {
    gtk::init();

    let mut window = gtk::Window::new(gtk::WindowType::TopLevel).unwrap();

    window.set_title("Enter your age");
    window.set_window_position(gtk::WindowPosition::Center);
    window.set_default_size(300, 20);

    let mut spin_button = gtk::SpinButton::new_with_range(0.0, 130.0, 1.0).unwrap();
    let slider = gtk::Scale::new_with_range(gtk::Orientation::Horizontal, 0.0, 130.0, 1.0).unwrap();

    Connect::connect(&spin_button, ValueChanged::new(&mut |&:| {
        let mut adjustment = slider.get_adjustment();

        adjustment.set_value(spin_button.get_value());
    }));

    Connect::connect(&slider, ValueChanged::new(&mut |&:| {
        let adjustment = slider.get_adjustment();

        spin_button.set_value(adjustment.get_value());
    }));

    let mut hbox = gtk::Box::new(gtk::Orientation::Horizontal, 5).unwrap();

    hbox.set_homogeneouse(true);
    hbox.add(&spin_button);
    hbox.add(&slider);

    Connect::connect(&window, DeleteEvent::new(&mut |_| {
        gtk::main_quit();
        true
    }));

    window.add(&hbox);
    window.show_all();
    gtk::main();
}<|endoftext|>


<commit_before>use std::collections::BTreeMap;
use std::string;

use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};

use super::MaxMindDBError;
use super::MaxMindDBError::DecodingError;

pub type DbArray = Vec<DataRecord>;
pub type DbMap = BTreeMap<string::String, DataRecord>;

#[derive(Clone, Debug, PartialEq)]
pub enum DataRecord {
    String(string::String),
    Double(f64),
    Byte(u8),
    Uint16(u16),
    Uint32(u32),
    Map(Box<DbMap>),
    Int32(i32),
    Uint64(u64),
    Boolean(bool),
    Array(DbArray),
    Float(f32),
    Null,
}

use self::DataRecord::{
    Array, Boolean, Byte, Double, Float, Int32, Map, Null, String, Uint16, Uint32, Uint64,
};

macro_rules! expect(
    ($e:expr, $t:ident) => ({
        match $e {
            $t(v) => Ok(v),
            other => Err(DecodingError(format!("Error decoding {:?} as {:?}",
                         other, stringify!($t))))
        }
    })
);

#[derive(Debug)]
pub struct Decoder {
    stack: Vec<DataRecord>,
}

impl Decoder {
    /// Creates a new decoder instance for decoding the specified JSON value.
    pub fn new(record: DataRecord) -> Decoder {
        Decoder {
            stack: vec![record],
        }
    }
}

impl Decoder {
    fn pop(&mut self) -> DataRecord {
        self.stack.pop().unwrap()
    }

    fn peek(&self) -> Option<&DataRecord> {
        self.stack.get(self.stack.len() - 1)
    }
}

pub type DecodeResult<T> = Result<T, MaxMindDBError>;

// Much of this code was borrowed from the Rust JSON library, Serde Deserializer example
impl<'de, 'a> de::Deserializer<'de> for &'a mut Decoder {
    type Error = MaxMindDBError;

    #[inline]
    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("deserialize_any");
        match self.peek() {
            Some(&String(_)) => self.deserialize_str(visitor),
            Some(&Double(_)) => self.deserialize_f64(visitor),
            Some(&Byte(_)) => self.deserialize_u8(visitor),
            Some(&Uint16(_)) => self.deserialize_u16(visitor),
            Some(&Uint32(_)) => self.deserialize_u32(visitor),
            Some(&Map(_)) => self.deserialize_map(visitor),
            Some(&Int32(_)) => self.deserialize_i32(visitor),
            Some(&Uint64(_)) => self.deserialize_u64(visitor),
            Some(&Boolean(_)) => self.deserialize_bool(visitor),
            Some(&Array(_)) => self.deserialize_seq(visitor),
            Some(&Float(_)) => self.deserialize_f32(visitor),
            Some(&Null) => self.deserialize_unit(visitor),
            None => Err(DecodingError("nothing left to deserialize".to_owned())),
        }
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u64");
        visitor.visit_u64(expect!(self.pop(), Uint64)?)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u32");
        visitor.visit_u32(expect!(self.pop(), Uint32)?)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u16");
        visitor.visit_u16(expect!(self.pop(), Uint16)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u8");
        visitor.visit_u8(expect!(self.pop(), Byte)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i64");
        self.deserialize_i32(visitor)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i32");
        visitor.visit_i32(expect!(self.pop(), Int32)?)
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_bool");
        visitor.visit_bool(expect!(self.pop(), Boolean)?)
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f64");
        visitor.visit_f64(expect!(self.pop(), Double)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f32");
        visitor.visit_f32(expect!(self.pop(), Float)?)
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        let string = expect!(self.pop(), String)?;
        debug!("read_str: {}", string);
        visitor.visit_str(&string)
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_string");
        self.deserialize_str(visitor)
    }

    // Structs look just like maps in JSON.
    //
    // Notice the `fields` parameter - a "struct" in the Serde data model means
    // that the `Deserialize` implementation is required to know what the fields
    // are before even looking at the input data. Any key-value pairing in which
    // the fields cannot be known ahead of time is probably a map.
    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    // Tuples look just like sequences in JSON. Some formats may be able to
    // represent tuples more efficiently.
    //
    // As indicated by the length parameter, the `Deserialize` implementation
    // for a tuple in the Serde data model is required to know the length of the
    // tuple before even looking at the input data.
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    // Tuple structs look just like sequences in JSON.
    fn deserialize_tuple_struct<V>(
        self,
        _name: &'static str,
        _len: usize,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_option()");
        match self.pop() {
            Null => visitor.visit_none(),
            value => {
                self.stack.push(value);
                visitor.visit_some(self)
            }
        }
    }

    // In Serde, unit means an anonymous value containing no data.
    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_nil");
        match self.pop() {
            Null => visitor.visit_unit(),
            other => Err(DecodingError(format!("Error decoding Null as {:?}", other))),
        }
    }

    // Unit struct means a named value containing no data.
    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_unit(visitor)
    }

    // As is done here, serializers are encouraged to treat newtype structs as
    // insignificant wrappers around the data they contain. That means not
    // parsing anything other than the contained value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    // An identifier in Serde is the type that identifies a field of a struct or
    // the variant of an enum.
    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_seq<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_seq()");
        let list = expect!(self.pop(), Array)?;
        let len = list.len();

        for v in list.into_iter().rev() {
            self.stack.push(v);
        }

        let value = visitor.visit_seq(ArrayAccess::new(&mut self, len))?;
        Ok(value)
    }

    // Much like `deserialize_seq` but calls the visitors `visit_map` method
    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
    // method with a `SeqAccess` implementation.
    fn deserialize_map<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_map()");
        let obj = expect!(self.pop(), Map)?;
        let len = obj.len();
        for (key, value) in obj.into_iter() {
            self.stack.push(value);
            self.stack.push(String(key));
        }

        let value = visitor.visit_map(MapAccessor::new(&mut self, len * 2))?;
        Ok(value)
    }

    forward_to_deserialize_any! {
        bytes byte_buf char enum i8 i16 ignored_any
    }
}

struct ArrayAccess<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> ArrayAccess<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        ArrayAccess { de, count }
    }
}

// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
// through elements of the sequence.
impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a> {
    type Error = MaxMindDBError;

    fn next_element_seed<T>(&mut self, seed: T) -> DecodeResult<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        // Check if there are no more elements.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize an array element.
        seed.deserialize(&mut *self.de).map(Some)
    }
}

struct MapAccessor<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> MapAccessor<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        MapAccessor { de, count }
    }
}

// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
// through entries of the map.
impl<'de, 'a> MapAccess<'de> for MapAccessor<'a> {
    type Error = MaxMindDBError;

    fn next_key_seed<K>(&mut self, seed: K) -> DecodeResult<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize a map key.
        seed.deserialize(&mut *self.de).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> DecodeResult<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Err(DecodingError("no more entries".to_owned()));
        }
        self.count -= 1;

        // Deserialize a map value.
        seed.deserialize(&mut *self.de)
    }
}
<commit_msg>Use .last() instead of .get(...len())<commit_after>use std::collections::BTreeMap;
use std::string;

use serde::de::{self, DeserializeSeed, MapAccess, SeqAccess, Visitor};

use super::MaxMindDBError;
use super::MaxMindDBError::DecodingError;

pub type DbArray = Vec<DataRecord>;
pub type DbMap = BTreeMap<string::String, DataRecord>;

#[derive(Clone, Debug, PartialEq)]
pub enum DataRecord {
    String(string::String),
    Double(f64),
    Byte(u8),
    Uint16(u16),
    Uint32(u32),
    Map(Box<DbMap>),
    Int32(i32),
    Uint64(u64),
    Boolean(bool),
    Array(DbArray),
    Float(f32),
    Null,
}

use self::DataRecord::{
    Array, Boolean, Byte, Double, Float, Int32, Map, Null, String, Uint16, Uint32, Uint64,
};

macro_rules! expect(
    ($e:expr, $t:ident) => ({
        match $e {
            $t(v) => Ok(v),
            other => Err(DecodingError(format!("Error decoding {:?} as {:?}",
                         other, stringify!($t))))
        }
    })
);

#[derive(Debug)]
pub struct Decoder {
    stack: Vec<DataRecord>,
}

impl Decoder {
    /// Creates a new decoder instance for decoding the specified JSON value.
    pub fn new(record: DataRecord) -> Decoder {
        Decoder {
            stack: vec![record],
        }
    }
}

impl Decoder {
    fn pop(&mut self) -> DataRecord {
        self.stack.pop().unwrap()
    }

    fn peek(&self) -> Option<&DataRecord> {
        self.stack.last()
    }
}

pub type DecodeResult<T> = Result<T, MaxMindDBError>;

// Much of this code was borrowed from the Rust JSON library, Serde Deserializer example
impl<'de, 'a> de::Deserializer<'de> for &'a mut Decoder {
    type Error = MaxMindDBError;

    #[inline]
    fn deserialize_any<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("deserialize_any");
        match self.peek() {
            Some(&String(_)) => self.deserialize_str(visitor),
            Some(&Double(_)) => self.deserialize_f64(visitor),
            Some(&Byte(_)) => self.deserialize_u8(visitor),
            Some(&Uint16(_)) => self.deserialize_u16(visitor),
            Some(&Uint32(_)) => self.deserialize_u32(visitor),
            Some(&Map(_)) => self.deserialize_map(visitor),
            Some(&Int32(_)) => self.deserialize_i32(visitor),
            Some(&Uint64(_)) => self.deserialize_u64(visitor),
            Some(&Boolean(_)) => self.deserialize_bool(visitor),
            Some(&Array(_)) => self.deserialize_seq(visitor),
            Some(&Float(_)) => self.deserialize_f32(visitor),
            Some(&Null) => self.deserialize_unit(visitor),
            None => Err(DecodingError("nothing left to deserialize".to_owned())),
        }
    }

    fn deserialize_u64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u64");
        visitor.visit_u64(expect!(self.pop(), Uint64)?)
    }

    fn deserialize_u32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u32");
        visitor.visit_u32(expect!(self.pop(), Uint32)?)
    }

    fn deserialize_u16<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u16");
        visitor.visit_u16(expect!(self.pop(), Uint16)?)
    }

    fn deserialize_u8<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_u8");
        visitor.visit_u8(expect!(self.pop(), Byte)?)
    }

    fn deserialize_i64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i64");
        self.deserialize_i32(visitor)
    }

    fn deserialize_i32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_i32");
        visitor.visit_i32(expect!(self.pop(), Int32)?)
    }

    fn deserialize_bool<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_bool");
        visitor.visit_bool(expect!(self.pop(), Boolean)?)
    }

    fn deserialize_f64<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f64");
        visitor.visit_f64(expect!(self.pop(), Double)?)
    }

    fn deserialize_f32<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_f32");
        visitor.visit_f32(expect!(self.pop(), Float)?)
    }

    fn deserialize_str<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        let string = expect!(self.pop(), String)?;
        debug!("read_str: {}", string);
        visitor.visit_str(&string)
    }

    fn deserialize_string<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_string");
        self.deserialize_str(visitor)
    }

    // Structs look just like maps in JSON.
    //
    // Notice the `fields` parameter - a "struct" in the Serde data model means
    // that the `Deserialize` implementation is required to know what the fields
    // are before even looking at the input data. Any key-value pairing in which
    // the fields cannot be known ahead of time is probably a map.
    fn deserialize_struct<V>(
        self,
        _name: &'static str,
        _fields: &'static [&'static str],
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_map(visitor)
    }

    // Tuples look just like sequences in JSON. Some formats may be able to
    // represent tuples more efficiently.
    //
    // As indicated by the length parameter, the `Deserialize` implementation
    // for a tuple in the Serde data model is required to know the length of the
    // tuple before even looking at the input data.
    fn deserialize_tuple<V>(self, _len: usize, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    // Tuple structs look just like sequences in JSON.
    fn deserialize_tuple_struct<V>(
        self,
        _name: &'static str,
        _len: usize,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_seq(visitor)
    }

    fn deserialize_option<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_option()");
        match self.pop() {
            Null => visitor.visit_none(),
            value => {
                self.stack.push(value);
                visitor.visit_some(self)
            }
        }
    }

    // In Serde, unit means an anonymous value containing no data.
    fn deserialize_unit<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_nil");
        match self.pop() {
            Null => visitor.visit_unit(),
            other => Err(DecodingError(format!("Error decoding Null as {:?}", other))),
        }
    }

    // Unit struct means a named value containing no data.
    fn deserialize_unit_struct<V>(self, _name: &'static str, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_unit(visitor)
    }

    // As is done here, serializers are encouraged to treat newtype structs as
    // insignificant wrappers around the data they contain. That means not
    // parsing anything other than the contained value.
    fn deserialize_newtype_struct<V>(
        self,
        _name: &'static str,
        visitor: V,
    ) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        visitor.visit_newtype_struct(self)
    }

    // An identifier in Serde is the type that identifies a field of a struct or
    // the variant of an enum.
    fn deserialize_identifier<V>(self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        self.deserialize_str(visitor)
    }

    fn deserialize_seq<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_seq()");
        let list = expect!(self.pop(), Array)?;
        let len = list.len();

        for v in list.into_iter().rev() {
            self.stack.push(v);
        }

        let value = visitor.visit_seq(ArrayAccess::new(&mut self, len))?;
        Ok(value)
    }

    // Much like `deserialize_seq` but calls the visitors `visit_map` method
    // with a `MapAccess` implementation, rather than the visitor's `visit_seq`
    // method with a `SeqAccess` implementation.
    fn deserialize_map<V>(mut self, visitor: V) -> DecodeResult<V::Value>
    where
        V: Visitor<'de>,
    {
        debug!("read_map()");
        let obj = expect!(self.pop(), Map)?;
        let len = obj.len();
        for (key, value) in obj.into_iter() {
            self.stack.push(value);
            self.stack.push(String(key));
        }

        let value = visitor.visit_map(MapAccessor::new(&mut self, len * 2))?;
        Ok(value)
    }

    forward_to_deserialize_any! {
        bytes byte_buf char enum i8 i16 ignored_any
    }
}

struct ArrayAccess<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> ArrayAccess<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        ArrayAccess { de, count }
    }
}

// `SeqAccess` is provided to the `Visitor` to give it the ability to iterate
// through elements of the sequence.
impl<'de, 'a> SeqAccess<'de> for ArrayAccess<'a> {
    type Error = MaxMindDBError;

    fn next_element_seed<T>(&mut self, seed: T) -> DecodeResult<Option<T::Value>>
    where
        T: DeserializeSeed<'de>,
    {
        // Check if there are no more elements.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize an array element.
        seed.deserialize(&mut *self.de).map(Some)
    }
}

struct MapAccessor<'a> {
    de: &'a mut Decoder,
    count: usize,
}

impl<'a> MapAccessor<'a> {
    fn new(de: &'a mut Decoder, count: usize) -> Self {
        MapAccessor { de, count }
    }
}

// `MapAccess` is provided to the `Visitor` to give it the ability to iterate
// through entries of the map.
impl<'de, 'a> MapAccess<'de> for MapAccessor<'a> {
    type Error = MaxMindDBError;

    fn next_key_seed<K>(&mut self, seed: K) -> DecodeResult<Option<K::Value>>
    where
        K: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Ok(None);
        }
        self.count -= 1;

        // Deserialize a map key.
        seed.deserialize(&mut *self.de).map(Some)
    }

    fn next_value_seed<V>(&mut self, seed: V) -> DecodeResult<V::Value>
    where
        V: DeserializeSeed<'de>,
    {
        // Check if there are no more entries.
        if self.count == 0 {
            return Err(DecodingError("no more entries".to_owned()));
        }
        self.count -= 1;

        // Deserialize a map value.
        seed.deserialize(&mut *self.de)
    }
}
<|endoftext|>


<commit_before>// Copyright 2015 Philipp Oppermann. See the README.md
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::entry::*;
use memory::{PAGE_SIZE, Frame, FrameAllocator};
use self::table::{Table, Level4};
use core::ptr::Unique;

mod entry;
mod table;
mod temporary_page;

const ENTRY_COUNT: usize = 512;

pub type PhysicalAddress = usize;
pub type VirtualAddress = usize;

#[derive(Debug, Clone, Copy)]
pub struct Page {
    number: usize,
}

impl Page {
    pub fn containing_address(address: VirtualAddress) -> Page {
        assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
                "invalid address: 0x{:x}",
                address);
        Page { number: address / PAGE_SIZE }
    }

    fn start_address(&self) -> usize {
        self.number * PAGE_SIZE
    }

    fn p4_index(&self) -> usize {
        (self.number >> 27) & 0o777
    }
    fn p3_index(&self) -> usize {
        (self.number >> 18) & 0o777
    }
    fn p2_index(&self) -> usize {
        (self.number >> 9) & 0o777
    }
    fn p1_index(&self) -> usize {
        (self.number >> 0) & 0o777
    }
}

pub struct ActivePageTable {
    p4: Unique<Table<Level4>>,
}

impl ActivePageTable {
    pub unsafe fn new() -> ActivePageTable {
        ActivePageTable { p4: Unique::new(table::P4) }
    }

    fn p4(&self) -> &Table<Level4> {
        unsafe { self.p4.get() }
    }

    fn p4_mut(&mut self) -> &mut Table<Level4> {
        unsafe { self.p4.get_mut() }
    }

    pub fn translate(&self, virtual_address: VirtualAddress) -> Option<PhysicalAddress> {
        let offset = virtual_address % PAGE_SIZE;
        self.translate_page(Page::containing_address(virtual_address))
            .map(|frame| frame.number * PAGE_SIZE + offset)
    }

    fn translate_page(&self, page: Page) -> Option<Frame> {
        let p3 = self.p4().next_table(page.p4_index());

        let huge_page = || {
            p3.and_then(|p3| {
                let p3_entry = &p3[page.p3_index()];
                // 1GiB page?
                if let Some(start_frame) = p3_entry.pointed_frame() {
                    if p3_entry.flags().contains(HUGE_PAGE) {
                        // address must be 1GiB aligned
                        assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
                        return Some(Frame {
                            number: start_frame.number + page.p2_index() * ENTRY_COUNT +
                                    page.p1_index(),
                        });
                    }
                }
                if let Some(p2) = p3.next_table(page.p3_index()) {
                    let p2_entry = &p2[page.p2_index()];
                    // 2MiB page?
                    if let Some(start_frame) = p2_entry.pointed_frame() {
                        if p2_entry.flags().contains(HUGE_PAGE) {
                            // address must be 2MiB aligned
                            assert!(start_frame.number % ENTRY_COUNT == 0);
                            return Some(Frame { number: start_frame.number + page.p1_index() });
                        }
                    }
                }
                None
            })
        };

        p3.and_then(|p3| p3.next_table(page.p3_index()))
          .and_then(|p2| p2.next_table(page.p2_index()))
          .and_then(|p1| p1[page.p1_index()].pointed_frame())
          .or_else(huge_page)
    }

    pub fn map_to<A>(&mut self, page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let mut p3 = self.p4_mut().next_table_create(page.p4_index(), allocator);
        let mut p2 = p3.next_table_create(page.p3_index(), allocator);
        let mut p1 = p2.next_table_create(page.p2_index(), allocator);

        assert!(p1[page.p1_index()].is_unused());
        p1[page.p1_index()].set(frame, flags | PRESENT);
    }

    pub fn map<A>(&mut self, page: Page, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let frame = allocator.allocate_frame().expect("out of memory");
        self.map_to(page, frame, flags, allocator)
    }

    pub fn identity_map<A>(&mut self, frame: Frame, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let page = Page::containing_address(frame.start_address());
        self.map_to(page, frame, flags, allocator)
    }

    fn unmap<A>(&mut self, page: Page, allocator: &mut A)
        where A: FrameAllocator
    {
        assert!(self.translate(page.start_address()).is_some());

        let p1 = self.p4_mut()
                     .next_table_mut(page.p4_index())
                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
                     .and_then(|p2| p2.next_table_mut(page.p2_index()))
                     .expect("mapping code does not support huge pages");
        let frame = p1[page.p1_index()].pointed_frame().unwrap();
        p1[page.p1_index()].set_unused();
        unsafe { ::x86::tlb::flush(page.start_address()) };
        // TODO free p(1,2,3) table if empty
        // allocator.deallocate_frame(frame);
    }
}

pub struct InactivePageTable {
    p4_frame: Frame,
}

impl InactivePageTable {
    pub fn new(frame: Frame) -> InactivePageTable {
        // TODO zero and recursive map the frame
        InactivePageTable { p4_frame: frame }
    }
}

pub fn test_paging<A>(allocator: &mut A)
    where A: FrameAllocator
{
    let mut page_table = unsafe { ActivePageTable::new() };

    // test translate
    println!("Some = {:?}", page_table.translate(0));
    println!("Some = {:?}", page_table.translate(4096)); // second P1 entry
    println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry
    println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry
    println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry
    println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte

    // test map_to
    let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
    let page = Page::containing_address(addr);
    let frame = allocator.allocate_frame().expect("no more frames");
    println!("None = {:?}, map to {:?}",
             page_table.translate(addr),
             frame);
    page_table.map_to(page, frame, EntryFlags::empty(), allocator);
    println!("Some = {:?}", page_table.translate(addr));
    println!("next free frame: {:?}", allocator.allocate_frame());

    // test unmap
    println!("{:#x}",
             unsafe { *(Page::containing_address(addr).start_address() as *const u64) });
    page_table.unmap(Page::containing_address(addr), allocator);
    println!("None = {:?}", page_table.translate(addr));
}
<commit_msg>Zero and recursive map inactive table on creation<commit_after>// Copyright 2015 Philipp Oppermann. See the README.md
// file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

pub use self::entry::*;
use memory::{PAGE_SIZE, Frame, FrameAllocator};
use self::table::{Table, Level4};
use self::temporary_page::TemporaryPage;
use core::ptr::Unique;

mod entry;
mod table;
mod temporary_page;

const ENTRY_COUNT: usize = 512;

pub type PhysicalAddress = usize;
pub type VirtualAddress = usize;

#[derive(Debug, Clone, Copy)]
pub struct Page {
    number: usize,
}

impl Page {
    pub fn containing_address(address: VirtualAddress) -> Page {
        assert!(address < 0x0000_8000_0000_0000 || address >= 0xffff_8000_0000_0000,
                "invalid address: 0x{:x}",
                address);
        Page { number: address / PAGE_SIZE }
    }

    fn start_address(&self) -> usize {
        self.number * PAGE_SIZE
    }

    fn p4_index(&self) -> usize {
        (self.number >> 27) & 0o777
    }
    fn p3_index(&self) -> usize {
        (self.number >> 18) & 0o777
    }
    fn p2_index(&self) -> usize {
        (self.number >> 9) & 0o777
    }
    fn p1_index(&self) -> usize {
        (self.number >> 0) & 0o777
    }
}

pub struct ActivePageTable {
    p4: Unique<Table<Level4>>,
}

impl ActivePageTable {
    pub unsafe fn new() -> ActivePageTable {
        ActivePageTable { p4: Unique::new(table::P4) }
    }

    fn p4(&self) -> &Table<Level4> {
        unsafe { self.p4.get() }
    }

    fn p4_mut(&mut self) -> &mut Table<Level4> {
        unsafe { self.p4.get_mut() }
    }

    pub fn translate(&self, virtual_address: VirtualAddress) -> Option<PhysicalAddress> {
        let offset = virtual_address % PAGE_SIZE;
        self.translate_page(Page::containing_address(virtual_address))
            .map(|frame| frame.number * PAGE_SIZE + offset)
    }

    fn translate_page(&self, page: Page) -> Option<Frame> {
        let p3 = self.p4().next_table(page.p4_index());

        let huge_page = || {
            p3.and_then(|p3| {
                let p3_entry = &p3[page.p3_index()];
                // 1GiB page?
                if let Some(start_frame) = p3_entry.pointed_frame() {
                    if p3_entry.flags().contains(HUGE_PAGE) {
                        // address must be 1GiB aligned
                        assert!(start_frame.number % (ENTRY_COUNT * ENTRY_COUNT) == 0);
                        return Some(Frame {
                            number: start_frame.number + page.p2_index() * ENTRY_COUNT +
                                    page.p1_index(),
                        });
                    }
                }
                if let Some(p2) = p3.next_table(page.p3_index()) {
                    let p2_entry = &p2[page.p2_index()];
                    // 2MiB page?
                    if let Some(start_frame) = p2_entry.pointed_frame() {
                        if p2_entry.flags().contains(HUGE_PAGE) {
                            // address must be 2MiB aligned
                            assert!(start_frame.number % ENTRY_COUNT == 0);
                            return Some(Frame { number: start_frame.number + page.p1_index() });
                        }
                    }
                }
                None
            })
        };

        p3.and_then(|p3| p3.next_table(page.p3_index()))
          .and_then(|p2| p2.next_table(page.p2_index()))
          .and_then(|p1| p1[page.p1_index()].pointed_frame())
          .or_else(huge_page)
    }

    pub fn map_to<A>(&mut self, page: Page, frame: Frame, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let mut p3 = self.p4_mut().next_table_create(page.p4_index(), allocator);
        let mut p2 = p3.next_table_create(page.p3_index(), allocator);
        let mut p1 = p2.next_table_create(page.p2_index(), allocator);

        assert!(p1[page.p1_index()].is_unused());
        p1[page.p1_index()].set(frame, flags | PRESENT);
    }

    pub fn map<A>(&mut self, page: Page, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let frame = allocator.allocate_frame().expect("out of memory");
        self.map_to(page, frame, flags, allocator)
    }

    pub fn identity_map<A>(&mut self, frame: Frame, flags: EntryFlags, allocator: &mut A)
        where A: FrameAllocator
    {
        let page = Page::containing_address(frame.start_address());
        self.map_to(page, frame, flags, allocator)
    }

    fn unmap<A>(&mut self, page: Page, allocator: &mut A)
        where A: FrameAllocator
    {
        assert!(self.translate(page.start_address()).is_some());

        let p1 = self.p4_mut()
                     .next_table_mut(page.p4_index())
                     .and_then(|p3| p3.next_table_mut(page.p3_index()))
                     .and_then(|p2| p2.next_table_mut(page.p2_index()))
                     .expect("mapping code does not support huge pages");
        let frame = p1[page.p1_index()].pointed_frame().unwrap();
        p1[page.p1_index()].set_unused();
        unsafe { ::x86::tlb::flush(page.start_address()) };
        // TODO free p(1,2,3) table if empty
        // allocator.deallocate_frame(frame);
    }
}

pub struct InactivePageTable {
    p4_frame: Frame,
}

impl InactivePageTable {
    pub fn new(frame: Frame,
               active_table: &mut ActivePageTable,
               temporary_page: &mut TemporaryPage)
               -> InactivePageTable {
        {
            let table = temporary_page.map_table_frame(frame.clone(), active_table);
            table.zero();
            table[511].set(frame.clone(), PRESENT | WRITABLE);
        }
        temporary_page.unmap(active_table);

        InactivePageTable { p4_frame: frame }
    }
}

pub fn test_paging<A>(allocator: &mut A)
    where A: FrameAllocator
{
    let mut page_table = unsafe { ActivePageTable::new() };

    // test translate
    println!("Some = {:?}", page_table.translate(0));
    println!("Some = {:?}", page_table.translate(4096)); // second P1 entry
    println!("Some = {:?}", page_table.translate(512 * 4096)); // second P2 entry
    println!("Some = {:?}", page_table.translate(300 * 512 * 4096)); // 300th P2 entry
    println!("None = {:?}", page_table.translate(512 * 512 * 4096)); // second P3 entry
    println!("Some = {:?}", page_table.translate(512 * 512 * 4096 - 1)); // last mapped byte

    // test map_to
    let addr = 42 * 512 * 512 * 4096; // 42th P3 entry
    let page = Page::containing_address(addr);
    let frame = allocator.allocate_frame().expect("no more frames");
    println!("None = {:?}, map to {:?}",
             page_table.translate(addr),
             frame);
    page_table.map_to(page, frame, EntryFlags::empty(), allocator);
    println!("Some = {:?}", page_table.translate(addr));
    println!("next free frame: {:?}", allocator.allocate_frame());

    // test unmap
    println!("{:#x}",
             unsafe { *(Page::containing_address(addr).start_address() as *const u64) });
    page_table.unmap(Page::containing_address(addr), allocator);
    println!("None = {:?}", page_table.translate(addr));
}
<|endoftext|>


<commit_before>use baseband::decode::{Decoder, Decider};
use baseband::sync::{SyncCorrelator, SyncDetector};
use error::{P25Error, Result};
use message::nid;
use message::status::{StreamSymbol, StatusDeinterleaver};

use self::State::*;
use self::StateChange::*;

const PRIME_SAMPLES: u32 = 6000;

#[derive(Debug)]
pub enum ReceiverEvent {
    Symbol(StreamSymbol),
    NetworkID(nid::NetworkID),
}

#[derive(Copy, Clone)]
struct Receiver {
    decoder: Decoder,
    status: StatusDeinterleaver,
}

impl Receiver {
    pub fn new(decoder: Decoder) -> Receiver {
        Receiver {
            decoder: decoder,
            status: StatusDeinterleaver::new(),
        }
    }

    pub fn feed(&mut self, s: f32) -> Option<StreamSymbol> {
        match self.decoder.feed(s) {
            Some(dibit) => Some(self.status.feed(dibit)),
            None => None,
        }
    }
}

enum State {
    Prime(u32),
    Sync(SyncDetector),
    DecodeNID(Receiver, nid::NIDReceiver),
    DecodePacket(Receiver),
    FlushPads(Receiver),
}

enum StateChange {
    Change(State),
    Event(ReceiverEvent),
    EventChange(ReceiverEvent, State),
    Error(P25Error),
    NoChange,
}

impl State {
    pub fn prime() -> State { Prime(1) }
    pub fn sync() -> State { Sync(SyncDetector::new()) }
    pub fn decode_nid(decoder: Decoder) -> State {
        DecodeNID(Receiver::new(decoder), nid::NIDReceiver::new())
    }
    pub fn decode_packet(recv: Receiver) -> State { DecodePacket(recv) }
    pub fn flush_pads(recv: Receiver) -> State { FlushPads(recv) }
}

pub struct DataUnitReceiver {
    state: State,
    corr: SyncCorrelator,
}

impl DataUnitReceiver {
    pub fn new() -> DataUnitReceiver {
        DataUnitReceiver {
            state: State::prime(),
            corr: SyncCorrelator::new(),
        }
    }

    pub fn flush_pads(&mut self) {
        match self.state {
            DecodePacket(recv) => self.state = State::flush_pads(recv),
            Sync(_) => {},
            _ => panic!("not decoding a packet"),
        }
    }

    pub fn resync(&mut self) { self.state = State::sync(); }

    fn handle(&mut self, s: f32) -> StateChange {
        let (power, thresh) = self.corr.feed(s);

        match self.state {
            Prime(t) => if t == PRIME_SAMPLES {
                Change(State::sync())
            } else {
                Change(Prime(t + 1))
            },
            Sync(ref mut sync) => if sync.feed(power, thresh) {
                let (p, m, n) = self.corr.thresholds();
                Change(State::decode_nid(Decoder::new(Decider::new(p, m, n))))
            } else {
                NoChange
            },
            DecodeNID(ref mut recv, ref mut nid) => {
                let dibit = match recv.feed(s) {
                    Some(StreamSymbol::Data(d)) => d,
                    Some(s) => return Event(ReceiverEvent::Symbol(s)),
                    None => return NoChange,
                };

                match nid.feed(dibit) {
                    Some(Ok(nid)) => EventChange(ReceiverEvent::NetworkID(nid),
                                                 State::decode_packet(*recv)),
                    Some(Err(e)) => Error(e),
                    None => NoChange,
                }
            },
            DecodePacket(ref mut recv) => match recv.feed(s) {
                Some(x) => Event(ReceiverEvent::Symbol(x)),
                None => NoChange,
            },
            FlushPads(ref mut recv) => match recv.feed(s) {
                Some(StreamSymbol::Status(_)) => Change(State::sync()),
                _ => NoChange,
            },
        }
    }

    pub fn feed(&mut self, s: f32) -> Option<Result<ReceiverEvent>> {
        match self.handle(s) {
            Change(state) => {
                self.state = state;
                None
            },
            Event(event) => Some(Ok(event)),
            EventChange(event, state) => {
                self.state = state;
                Some(Ok(event))
            },
            Error(err) => Some(Err(err)),
            NoChange => None,
        }
    }
}
<commit_msg>Document data_unit module<commit_after>//! General low-level receiver for all data units, covering frame synchronization up to
//! symbol decoding.

use baseband::decode::{Decoder, Decider};
use baseband::sync::{SyncCorrelator, SyncDetector};
use error::{P25Error, Result};
use message::nid;
use message::status::{StreamSymbol, StatusDeinterleaver};

use self::State::*;
use self::StateChange::*;

/// Number of samples used to initially prime the correlator's moving average before starting to
/// look for sync.
const PRIME_SAMPLES: u32 = 6000;

/// Low-level receiver for decoding samples into symbols and deinterleaving status
/// symbols.
#[derive(Copy, Clone)]
struct SymbolReceiver {
    /// Symbol decoder.
    decoder: Decoder,
    /// Data/Status symbol deinterleaver.
    status: StatusDeinterleaver,
}

impl SymbolReceiver {
    /// Create a new `SymbolReceiver` using the given symbol decoder.
    pub fn new(decoder: Decoder) -> SymbolReceiver {
        SymbolReceiver {
            decoder: decoder,
            status: StatusDeinterleaver::new(),
        }
    }

    /// Feed in a baseband symbol, possibly producing a data or status symbol.
    pub fn feed(&mut self, s: f32) -> Option<StreamSymbol> {
        match self.decoder.feed(s) {
            Some(dibit) => Some(self.status.feed(dibit)),
            None => None,
        }
    }
}

/// An event seen by the low-level receiver.
#[derive(Debug)]
pub enum ReceiverEvent {
    /// Data or status symbol.
    Symbol(StreamSymbol),
    /// Decoded NID information.
    NetworkID(nid::NetworkID),
}

/// Internal state of the state machine.
enum State {
    /// Prime the signal power tracker.
    Prime(u32),
    /// Lock onto frame synchronization.
    Sync(SyncDetector),
    /// Decode NID.
    DecodeNID(SymbolReceiver, nid::NIDReceiver),
    /// Decode data and status symbols.
    DecodePacket(SymbolReceiver),
    /// Flush pads at end of packet.
    FlushPads(SymbolReceiver),
}

/// Action the state machine should take.
enum StateChange {
    /// Change to the given state.
    Change(State),
    /// Propagate the given event.
    Event(ReceiverEvent),
    /// Change to the given state and propagate the given event.
    EventChange(ReceiverEvent, State),
    /// Propagate the given error.
    Error(P25Error),
    /// No action necessary.
    NoChange,
}

impl State {
    /// Initial prime state.
    pub fn prime() -> State { Prime(1) }

    /// Initial synchronization state.
    pub fn sync() -> State { Sync(SyncDetector::new()) }

    /// Initial NID decode state.
    pub fn decode_nid(decoder: Decoder) -> State {
        DecodeNID(SymbolReceiver::new(decoder), nid::NIDReceiver::new())
    }

    /// Initial symbol decode state.
    pub fn decode_packet(recv: SymbolReceiver) -> State { DecodePacket(recv) }

    /// Initial flush padding state.
    pub fn flush_pads(recv: SymbolReceiver) -> State { FlushPads(recv) }
}

/// State machine for low-level data unit reception.
///
/// The state machine consumes baseband samples and performs the following steps common to
/// all data units:
///
/// 1. Track average power of input signal
/// 2. Lock onto frame synchronization
/// 3. Deinterleave status symbols
/// 4. Decode NID information
/// 5. Decode dibit symbol until stopped
pub struct DataUnitReceiver {
    /// Current state.
    state: State,
    /// Tracks input signal power and frame synchronization statistics.
    corr: SyncCorrelator,
}

impl DataUnitReceiver {
    /// Create a new `DataUnitReceiver` in the initial reception state.
    pub fn new() -> DataUnitReceiver {
        DataUnitReceiver {
            state: State::prime(),
            corr: SyncCorrelator::new(),
        }
    }

    /// Flush any remaining padding symbols at the end of the current packet, and reenter
    /// the frame synchronization state afterwards.
    pub fn flush_pads(&mut self) {
        match self.state {
            DecodePacket(recv) => self.state = State::flush_pads(recv),
            Sync(_) => {},
            _ => panic!("not decoding a packet"),
        }
    }

    /// Force the receiver into frame synchronization.
    pub fn resync(&mut self) { self.state = State::sync(); }

    /// Determine the next action to take based on the given sample.
    fn handle(&mut self, s: f32) -> StateChange {
        // Continuously track the input signal power.
        let (power, thresh) = self.corr.feed(s);

        match self.state {
            Prime(t) => if t == PRIME_SAMPLES {
                Change(State::sync())
            } else {
                Change(Prime(t + 1))
            },
            Sync(ref mut sync) => if sync.feed(power, thresh) {
                let (p, m, n) = self.corr.thresholds();
                Change(State::decode_nid(Decoder::new(Decider::new(p, m, n))))
            } else {
                NoChange
            },
            DecodeNID(ref mut recv, ref mut nid) => {
                let dibit = match recv.feed(s) {
                    Some(StreamSymbol::Data(d)) => d,
                    Some(s) => return Event(ReceiverEvent::Symbol(s)),
                    None => return NoChange,
                };

                match nid.feed(dibit) {
                    Some(Ok(nid)) => EventChange(ReceiverEvent::NetworkID(nid),
                                                 State::decode_packet(*recv)),
                    Some(Err(e)) => Error(e),
                    None => NoChange,
                }
            },
            DecodePacket(ref mut recv) => match recv.feed(s) {
                Some(x) => Event(ReceiverEvent::Symbol(x)),
                None => NoChange,
            },
            FlushPads(ref mut recv) => match recv.feed(s) {
                /// According to the spec, the stream is padded until the next status
                /// symbol boundary.
                Some(StreamSymbol::Status(_)) => Change(State::sync()),
                _ => NoChange,
            },
        }
    }

    /// Feed in a baseband symbol, possibly producing a receiver event. Return
    /// `Some(Ok(event))` for any normal event, `Some(Err(err))` for any error, and `None`
    /// if no event occurred.
    pub fn feed(&mut self, s: f32) -> Option<Result<ReceiverEvent>> {
        match self.handle(s) {
            Change(state) => {
                self.state = state;
                None
            },
            Event(event) => Some(Ok(event)),
            EventChange(event, state) => {
                self.state = state;
                Some(Ok(event))
            },
            Error(err) => Some(Err(err)),
            NoChange => None,
        }
    }
}
<|endoftext|>