From 1cea37cbff4a36c72db9fda9eeb79f30e9832059 Mon Sep 17 00:00:00 2001 From: Adam Reichold Date: Tue, 11 Jun 2019 19:23:32 +0200 Subject: [PATCH] Improve memory locality of checking for duplicate exports Using a sorted slice gives us the same O(N log N) worst case execution time as using a BTreeMap, but using a single allocation as with HashMap, so that we should see better memory locality and hence better constant factors when checking for duplicate exports. --- validation/src/lib.rs | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/validation/src/lib.rs b/validation/src/lib.rs index d2d0713..4815b0a 100644 --- a/validation/src/lib.rs +++ b/validation/src/lib.rs @@ -27,12 +27,10 @@ use core::fmt; #[cfg(feature = "std")] use std::error; -use alloc::collections::BTreeSet; - use self::context::ModuleContextBuilder; use parity_wasm::elements::{ - BlockType, External, FuncBody, GlobalEntry, GlobalType, InitExpr, Instruction, Internal, - MemoryType, Module, ResizableLimits, TableType, Type, ValueType, + BlockType, ExportEntry, External, FuncBody, GlobalEntry, GlobalType, InitExpr, Instruction, + Internal, MemoryType, Module, ResizableLimits, TableType, Type, ValueType, }; pub mod context; @@ -247,13 +245,21 @@ pub fn validate_module(module: &Module) -> Result>(); + + export_names.sort_unstable(); + + for (fst, snd) in export_names.iter().zip(export_names.iter().skip(1)) { + if fst == snd { + return Err(Error(format!("duplicate export {}", fst))); } + } + + for export in export_section.entries() { match *export.internal() { Internal::Function(function_index) => { context.require_function(function_index)?;