From ba6e9816f5478fcf968a21aa60dc85e1d81d4add Mon Sep 17 00:00:00 2001 From: Markus Westerlind Date: Sat, 21 Apr 2018 08:48:07 +0200 Subject: [PATCH] perf(parser): Reuse the same Kind allocation in the parser --- base/src/ast.rs | 3 ++- base/src/kind.rs | 3 +-- base/src/lib.rs | 4 +++- base/src/types/mod.rs | 6 ++++-- benches/parser.rs | 2 +- parser/src/grammar.lalrpop | 12 ++++++------ parser/src/lib.rs | 4 ++-- vm/src/api/typ.rs | 4 ++-- vm/src/vm.rs | 2 +- 9 files changed, 22 insertions(+), 18 deletions(-) diff --git a/base/src/ast.rs b/base/src/ast.rs index 0433df632f..f37cb9ca8a 100644 --- a/base/src/ast.rs +++ b/base/src/ast.rs @@ -556,7 +556,8 @@ pub fn walk_mut_expr<'a, V: ?Sized + MutVisitor<'a>>(v: &mut V, e: &'a mut Spann } Expr::Ident(ref mut id) => v.visit_ident(id), Expr::MacroExpansion { - ref mut replacement, .. + ref mut replacement, + .. } => v.visit_expr(replacement), Expr::Literal(..) | Expr::Error(..) => (), } diff --git a/base/src/kind.rs b/base/src/kind.rs index 403b445653..f3c8066dd3 100644 --- a/base/src/kind.rs +++ b/base/src/kind.rs @@ -26,7 +26,6 @@ impl KindEnv for EmptyEnv { } } - /// Kind representation /// /// All types in gluon has a kind. Most types encountered are of the `Type` kind which @@ -179,7 +178,7 @@ impl fmt::Display for ArcKind { } } -type_cache! { KindCache() { ArcKind, Kind } row hole typ } +type_cache! { KindCache() () { ArcKind, Kind } row hole typ } impl<'a, F: ?Sized> Walker<'a, ArcKind> for F where diff --git a/base/src/lib.rs b/base/src/lib.rs index 57ecab1d1d..7358eb65d2 100644 --- a/base/src/lib.rs +++ b/base/src/lib.rs @@ -26,10 +26,11 @@ extern crate serde_derive_state; extern crate serde_state as serde; macro_rules! type_cache { - ($name: ident ($($args: ident),*) { $typ: ty, $inner_type: ident } $( $id: ident )+) => { + ($name: ident ($($args: ident),*) ($($arg: ident : $arg_type: ty),*) { $typ: ty, $inner_type: ident } $( $id: ident )+) => { #[derive(Debug, Clone)] pub struct $name<$($args),*> { + $(pub $arg : $arg_type,)* $(pub $id : $typ,)+ _marker: ::std::marker::PhantomData<( $($args),* )>, } @@ -47,6 +48,7 @@ macro_rules! type_cache { { pub fn new() -> Self { $name { + $($arg: <$arg_type>::default(),)* $( $id : $inner_type::$id(), )+ diff --git a/base/src/types/mod.rs b/base/src/types/mod.rs index 251d06e57b..3f00d52775 100644 --- a/base/src/types/mod.rs +++ b/base/src/types/mod.rs @@ -58,7 +58,6 @@ impl TypeEnv for EmptyEnv { } } - /// Trait which is a `TypeEnv` which also provides access to the type representation of some /// primitive types pub trait PrimitiveEnv: TypeEnv { @@ -71,7 +70,10 @@ impl<'a, T: ?Sized + PrimitiveEnv> PrimitiveEnv for &'a T { } } -type_cache! { TypeCache(Id, T) { T, Type } +type_cache! { + TypeCache(Id, T) + (kind_cache: ::kind::KindCache) + { T, Type } hole opaque int byte float string char function_builtin array_builtin unit empty_row } diff --git a/benches/parser.rs b/benches/parser.rs index 66b507415b..2e3cb0aac3 100644 --- a/benches/parser.rs +++ b/benches/parser.rs @@ -20,7 +20,7 @@ fn prelude(b: &mut Bencher) { b.iter(|| { let mut symbols = Symbols::new(); let mut symbols = SymbolModule::new("".into(), &mut symbols); - let expr = parser::parse_expr(&mut symbols, &TypeCache::new(), &text) + let expr = parser::parse_expr(&mut symbols, &TypeCache::default(), &text) .unwrap_or_else(|err| panic!("{:?}", err)); black_box(expr) }) diff --git a/parser/src/grammar.lalrpop b/parser/src/grammar.lalrpop index a1512d3175..9dfc67371b 100644 --- a/parser/src/grammar.lalrpop +++ b/parser/src/grammar.lalrpop @@ -122,9 +122,9 @@ AtomicKind: ArcKind = { use lalrpop_util::ParseError; match id { - "_" => Ok(Kind::hole()), - "Type" => Ok(Kind::typ()), - "Row" => Ok(Kind::row()), + "_" => Ok(type_cache.kind_cache.hole()), + "Type" => Ok(type_cache.kind_cache.typ()), + "Row" => Ok(type_cache.kind_cache.row()), id => Err(ParseError::User { error: pos::spanned2( l.into(), @@ -150,7 +150,7 @@ Kind: ArcKind = { TypeParam: Generic = { => - Generic::new(id, Kind::hole()), + Generic::new(id, type_cache.kind_cache.hole()), "(" ":" ")" => Generic::new(id, kind), @@ -219,7 +219,7 @@ AtomicType_: Type> = { Type::Ident(env.from_str(last)) } Err(_) => { - Type::Generic(Generic::new(env.from_str(last), Kind::hole())) + Type::Generic(Generic::new(env.from_str(last), type_cache.kind_cache.hole())) } } } @@ -268,7 +268,7 @@ Type_ = { AppType_, "forall" "." => Type::Forall(args.into_iter() - .map(|id| Generic::new(id, Kind::variable(0))) + .map(|id| Generic::new(id, type_cache.kind_cache.hole())) .collect(), ty, None), diff --git a/parser/src/lib.rs b/parser/src/lib.rs index 3cb3d1b55e..c07bb9797f 100644 --- a/parser/src/lib.rs +++ b/parser/src/lib.rs @@ -403,7 +403,7 @@ where let mut parse_errors = Errors::new(); - let type_cache = TypeCache::new(); + let type_cache = TypeCache::default(); let result = grammar::LetOrExprParser::new().parse(&type_cache, symbols, &mut parse_errors, layout); @@ -442,7 +442,7 @@ pub fn parse_string<'env, 'input>( symbols: &'env mut IdentEnv, input: &'input str, ) -> Result, (Option>, ParseErrors)> { - parse_partial_expr(symbols, &TypeCache::new(), input) + parse_partial_expr(symbols, &TypeCache::default(), input) } pub fn reparse_infix( diff --git a/vm/src/api/typ.rs b/vm/src/api/typ.rs index b566bb64b2..0c0e549901 100644 --- a/vm/src/api/typ.rs +++ b/vm/src/api/typ.rs @@ -5,7 +5,7 @@ use base::symbol::{Symbol, Symbols}; use {Error as VmError, Result}; use api::VmType; -use thread::Thread; +use thread::{Thread, ThreadInternal}; use serde::de::{self, DeserializeOwned, DeserializeSeed, EnumAccess, Error, IntoDeserializer, MapAccess, SeqAccess, VariantAccess, Visitor}; @@ -37,7 +37,7 @@ fn from_rust_(symbols: &mut Symbols, thread: &Thread) -> Result<(String, ArcT where T: DeserializeOwned, { - let type_cache = TypeCache::new(); + let type_cache = thread.global_env().type_cache(); let mut deserializer = Deserializer::from_value(&type_cache, thread, symbols); T::deserialize(&mut deserializer)?; let mut variants = Vec::new(); diff --git a/vm/src/vm.rs b/vm/src/vm.rs index 27f601f4b8..843de4eb3b 100644 --- a/vm/src/vm.rs +++ b/vm/src/vm.rs @@ -394,7 +394,7 @@ impl GlobalVmStateBuilder { interner: RwLock::new(Interner::new()), gc: Mutex::new(Gc::new(Generation::default(), usize::MAX)), macros: MacroEnv::new(), - type_cache: TypeCache::new(), + type_cache: TypeCache::default(), generation_0_threads: RwLock::new(Vec::new()), #[cfg(not(target_arch = "wasm32"))]