Changeset - 97b87404ffa5
[Not reviewed]
0 5 0
mh - 4 years ago 2021-12-16 10:34:10
contact@maxhenger.nl
WIP on performance fixes
5 files changed with 81 insertions and 50 deletions:
0 comments (0 inline, 0 general)
src/collections/scoped_buffer.rs
Show inline comments
 
@@ -26,7 +26,7 @@ pub(crate) struct ScopedSection<T: Sized> {
 
}
 

	
 
impl<T: Sized> ScopedBuffer<T> {
 
    pub(crate) fn new_reserved(capacity: usize) -> Self {
 
    pub(crate) fn with_capacity(capacity: usize) -> Self {
 
        Self { inner: Vec::with_capacity(capacity) }
 
    }
 

	
 
@@ -106,6 +106,16 @@ impl<T: Sized> ScopedSection<T> {
 
    }
 
}
 

	
 
impl<T: Copy> ScopedSection<T> {
 
    pub(crate) fn iter_copied(&self) -> ScopedIter<T> {
 
        return ScopedIter{
 
            inner: self.inner,
 
            cur_index: self.start_size,
 
            last_index: unsafe{ (*self.inner).len() as u32 },
 
        }
 
    }
 
}
 

	
 
impl<T: Sized> std::ops::Index<usize> for ScopedSection<T> {
 
    type Output = T;
 

	
 
@@ -123,3 +133,24 @@ impl<T: Sized> Drop for ScopedSection<T> {
 
        vec.truncate(self.start_size as usize);
 
    }
 
}
 

	
 
pub(crate) struct ScopedIter<T: Copy> {
 
    inner: *mut Vec<T>,
 
    cur_index: u32,
 
    last_index: u32,
 
}
 

	
 
impl<T: Copy> Iterator for ScopedIter<T> {
 
    type Item = T;
 

	
 
    fn next(&mut self) -> Option<Self::Item> {
 
        if self.cur_index >= self.last_index {
 
            return None;
 
        }
 

	
 
        let vec = unsafe{ &*self.inner };
 
        let index = self.cur_index as usize;
 
        self.cur_index += 1;
 
        return Some(vec[index]);
 
    }
 
}
 
\ No newline at end of file
src/protocol/parser/pass_definitions.rs
Show inline comments
 
@@ -31,13 +31,13 @@ impl PassDefinitions {
 
            cur_definition: DefinitionId::new_invalid(),
 
            type_parser: ParserTypeParser::new(),
 
            buffer: String::with_capacity(128),
 
            struct_fields: ScopedBuffer::new_reserved(128),
 
            enum_variants: ScopedBuffer::new_reserved(128),
 
            union_variants: ScopedBuffer::new_reserved(128),
 
            variables: ScopedBuffer::new_reserved(128),
 
            expressions: ScopedBuffer::new_reserved(128),
 
            statements: ScopedBuffer::new_reserved(128),
 
            parser_types: ScopedBuffer::new_reserved(128),
 
            struct_fields: ScopedBuffer::with_capacity(128),
 
            enum_variants: ScopedBuffer::with_capacity(128),
 
            union_variants: ScopedBuffer::with_capacity(128),
 
            variables: ScopedBuffer::with_capacity(128),
 
            expressions: ScopedBuffer::with_capacity(128),
 
            statements: ScopedBuffer::with_capacity(128),
 
            parser_types: ScopedBuffer::with_capacity(128),
 
        }
 
    }
 

	
src/protocol/parser/pass_typing.rs
Show inline comments
 
@@ -49,15 +49,14 @@ macro_rules! debug_log {
 

	
 
use std::collections::{HashMap, HashSet};
 

	
 
use crate::collections::DequeSet;
 
use crate::collections::{ScopedBuffer, DequeSet};
 
use crate::protocol::ast::*;
 
use crate::protocol::input_source::ParseError;
 
use crate::protocol::parser::ModuleCompilationPhase;
 
use crate::protocol::parser::type_table::*;
 
use crate::protocol::parser::token_parsing::*;
 
use super::visitor::{
 
    STMT_BUFFER_INIT_CAPACITY,
 
    EXPR_BUFFER_INIT_CAPACITY,
 
    BUFFER_INIT_CAPACITY,
 
    Ctx,
 
    Visitor,
 
    VisitorResult
 
@@ -858,11 +857,10 @@ pub(crate) struct PassTyping {
 
    reserved_idx: i32,
 
    definition_type: DefinitionType,
 
    poly_vars: Vec<ConcreteType>,
 

	
 
    // Buffers for iteration over substatements and subexpressions
 
    stmt_buffer: Vec<StatementId>,
 
    expr_buffer: Vec<ExpressionId>,
 

	
 
    var_buffer: ScopedBuffer<VariableId>,
 
    expr_buffer: ScopedBuffer<ExpressionId>,
 
    stmt_buffer: ScopedBuffer<StatementId>,
 
    // Mapping from parser type to inferred type. We attempt to continue to
 
    // specify these types until we're stuck or we've fully determined the type.
 
    var_types: HashMap<VariableId, VarData>,            // types of variables
 
@@ -922,8 +920,9 @@ impl PassTyping {
 
            reserved_idx: -1,
 
            definition_type: DefinitionType::Function(FunctionDefinitionId::new_invalid()),
 
            poly_vars: Vec::new(),
 
            stmt_buffer: Vec::with_capacity(STMT_BUFFER_INIT_CAPACITY),
 
            expr_buffer: Vec::with_capacity(EXPR_BUFFER_INIT_CAPACITY),
 
            var_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAPACITY),
 
            expr_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAPACITY),
 
            stmt_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAPACITY),
 
            var_types: HashMap::new(),
 
            expr_types: Vec::new(),
 
            extra_data: Vec::new(),
 
@@ -997,8 +996,6 @@ impl PassTyping {
 
        self.reserved_idx = -1;
 
        self.definition_type = DefinitionType::Function(FunctionDefinitionId::new_invalid());
 
        self.poly_vars.clear();
 
        self.stmt_buffer.clear();
 
        self.expr_buffer.clear();
 
        self.var_types.clear();
 
        self.expr_types.clear();
 
        self.extra_data.clear();
 
@@ -1024,12 +1021,14 @@ impl Visitor for PassTyping {
 
        self.expr_types.resize(comp_def.num_expressions_in_body as usize, Default::default());
 

	
 
        // Visit parameters
 
        for param_id in comp_def.parameters.clone() {
 
        let section = self.var_buffer.start_section_initialized(comp_def.parameters.as_slice());
 
        for param_id in section.iter_copied() {
 
            let param = &ctx.heap[param_id];
 
            let var_type = self.determine_inference_type_from_parser_type_elements(&param.parser_type.elements, true);
 
            debug_assert!(var_type.is_done, "expected component arguments to be concrete types");
 
            self.var_types.insert(param_id, VarData::new_local(var_type));
 
        }
 
        section.forget();
 

	
 
        // Visit the body and all of its expressions
 
        let body_stmt_id = ctx.heap[id].body;
 
@@ -1062,12 +1061,14 @@ impl Visitor for PassTyping {
 
        self.expr_types.resize(func_def.num_expressions_in_body as usize, Default::default());
 

	
 
        // Visit parameters
 
        for param_id in func_def.parameters.clone() {
 
        let section = self.var_buffer.start_section_initialized(func_def.parameters.as_slice());
 
        for param_id in section.iter_copied() {
 
            let param = &ctx.heap[param_id];
 
            let var_type = self.determine_inference_type_from_parser_type_elements(&param.parser_type.elements, true);
 
            debug_assert!(var_type.is_done, "expected function arguments to be concrete types");
 
            self.var_types.insert(param_id, VarData::new_local(var_type));
 
        }
 
        section.forget();
 

	
 
        // Visit all of the expressions within the body
 
        let body_stmt_id = ctx.heap[id].body;
 
@@ -1080,9 +1081,11 @@ impl Visitor for PassTyping {
 
        // Transfer statements for traversal
 
        let block = &ctx.heap[id];
 

	
 
        for stmt_id in block.statements.clone() {
 
        let section = self.stmt_buffer.start_section_initialized(block.statements.as_slice());
 
        for stmt_id in section.iter_copied() {
 
            self.visit_stmt(ctx, stmt_id)?;
 
        }
 
        section.forget();
 

	
 
        Ok(())
 
    }
 
@@ -1312,17 +1315,16 @@ impl Visitor for PassTyping {
 
                // No subexpressions
 
            },
 
            Literal::Struct(literal) => {
 
                // TODO: @performance
 
                let expr_ids: Vec<_> = literal.fields
 
                    .iter()
 
                    .map(|f| f.value)
 
                    .collect();
 

	
 
                let mut expr_ids = self.expr_buffer.start_section();
 
                for field in &literal.fields {
 
                    expr_ids.push(field.value);
 
                }
 
                self.insert_initial_struct_polymorph_data(ctx, id);
 

	
 
                for expr_id in expr_ids {
 
                for expr_id in expr_ids.iter_copied() {
 
                    self.visit_expr(ctx, expr_id)?;
 
                }
 
                expr_ids.forget();
 
            },
 
            Literal::Enum(_) => {
 
                // Enumerations do not carry any subexpressions, but may still
 
@@ -1333,20 +1335,20 @@ impl Visitor for PassTyping {
 
            },
 
            Literal::Union(literal) => {
 
                // May carry subexpressions and polymorphic arguments
 
                // TODO: @performance
 
                let expr_ids = literal.values.clone();
 
                let expr_ids = self.expr_buffer.start_section_initialized(literal.values.as_slice());
 
                self.insert_initial_union_polymorph_data(ctx, id);
 

	
 
                for expr_id in expr_ids {
 
                for expr_id in expr_ids.iter_copied() {
 
                    self.visit_expr(ctx, expr_id)?;
 
                }
 
                expr_ids.forget();
 
            },
 
            Literal::Array(expressions) | Literal::Tuple(expressions) => {
 
                // TODO: @performance
 
                let expr_ids = expressions.clone();
 
                for expr_id in expr_ids {
 
                let expr_ids = self.expr_buffer.start_section_initialized(expressions.as_slice());
 
                for expr_id in expr_ids.iter_copied() {
 
                    self.visit_expr(ctx, expr_id)?;
 
                }
 
                expr_ids.forget();
 
            }
 
        }
 

	
 
@@ -1377,9 +1379,11 @@ impl Visitor for PassTyping {
 
        self.expr_types[call_expr.unique_id_in_definition as usize].field_or_monomorph_idx = 0;
 

	
 
        // Visit all arguments
 
        for arg_expr_id in call_expr.arguments.clone() { // TODO: @Performance
 
        let expr_ids = self.expr_buffer.start_section_initialized(call_expr.arguments.as_slice());
 
        for arg_expr_id in expr_ids.iter_copied() {
 
            self.visit_expr(ctx, arg_expr_id)?;
 
        }
 
        expr_ids.forget();
 

	
 
        self.progress_call_expr(ctx, id)
 
    }
 
@@ -1622,7 +1626,7 @@ impl PassTyping {
 
    }
 

	
 
    fn progress_expr(&mut self, ctx: &mut Ctx, idx: i32) -> Result<(), ParseError> {
 
        let id = self.expr_types[idx as usize].expr_id; // TODO: @Temp
 
        let id = self.expr_types[idx as usize].expr_id;
 
        match &ctx.heap[id] {
 
            Expression::Assignment(expr) => {
 
                let id = expr.this;
 
@@ -2152,7 +2156,7 @@ impl PassTyping {
 
                // information is inserted into `extra_data`. Check to see if we can
 
                // do some mutual inference.
 
                let poly_data = &mut self.extra_data[extra_idx as usize];
 
                let mut poly_progress = HashSet::new();
 
                let mut poly_progress = HashSet::new(); // TODO: @Performance
 

	
 
                // Apply to struct's type
 
                let signature_type: *mut _ = &mut poly_data.embedded[0];
 
@@ -2518,6 +2522,7 @@ impl PassTyping {
 
                progress_expr
 
            },
 
            Literal::Array(data) => {
 
                // TODO: Continue here with performance improvements by reducing allocations
 
                let expr_elements = data.clone(); // TODO: @performance
 
                debug_log!("Array expr ({} elements): {}", expr_elements.len(), upcast_id.index);
 
                debug_log!(" * Before:");
src/protocol/parser/pass_validation_linking.rs
Show inline comments
 
@@ -42,8 +42,7 @@ use crate::protocol::parser::symbol_table::*;
 
use crate::protocol::parser::type_table::*;
 

	
 
use super::visitor::{
 
    STMT_BUFFER_INIT_CAPACITY,
 
    EXPR_BUFFER_INIT_CAPACITY,
 
    BUFFER_INIT_CAPACITY,
 
    Ctx,
 
    Visitor,
 
    VisitorResult
 
@@ -126,10 +125,10 @@ impl PassValidationLinking {
 
            must_be_assignable: None,
 
            relative_pos_in_block: 0,
 
            next_expr_index: 0,
 
            variable_buffer: ScopedBuffer::new_reserved(128),
 
            definition_buffer: ScopedBuffer::new_reserved(128),
 
            statement_buffer: ScopedBuffer::new_reserved(STMT_BUFFER_INIT_CAPACITY),
 
            expression_buffer: ScopedBuffer::new_reserved(EXPR_BUFFER_INIT_CAPACITY),
 
            variable_buffer: ScopedBuffer::with_capacity(128),
 
            definition_buffer: ScopedBuffer::with_capacity(128),
 
            statement_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAPACITY),
 
            expression_buffer: ScopedBuffer::with_capacity(BUFFER_INIT_CAPACITY),
 
        }
 
    }
 

	
src/protocol/parser/visitor.rs
Show inline comments
 
@@ -6,12 +6,8 @@ use crate::protocol::symbol_table::{SymbolTable};
 
type Unit = ();
 
pub(crate) type VisitorResult = Result<Unit, ParseError>;
 

	
 
/// Globally configured vector capacity for statement buffers in visitor 
 
/// implementations
 
pub(crate) const STMT_BUFFER_INIT_CAPACITY: usize = 256;
 
/// Globally configured vector capacity for expression buffers in visitor
 
/// implementations
 
pub(crate) const EXPR_BUFFER_INIT_CAPACITY: usize = 256;
 
/// Globally configured vector capacity for buffers in visitor implementations
 
pub(crate) const BUFFER_INIT_CAPACITY: usize = 256;
 

	
 
/// General context structure that is used while traversing the AST.
 
pub(crate) struct Ctx<'p> {
0 comments (0 inline, 0 general)