diff --git a/src/rose/rose_build_bytecode.cpp b/src/rose/rose_build_bytecode.cpp index 68812b44..3356d214 100644 --- a/src/rose/rose_build_bytecode.cpp +++ b/src/rose/rose_build_bytecode.cpp @@ -186,10 +186,6 @@ struct build_context : boost::noncopyable { */ size_t numStates = 0; - /** \brief Very simple cache from sparse iter to offset, used when building - * up iterators in early misc. */ - map, u32> iterCache; - /** \brief Simple cache of programs written to engine blob, used for * deduplication. */ ue2::unordered_map &iter) { - if (contains(bc.iterCache, iter)) { - DEBUG_PRINTF("cache hit\n"); - u32 offset = bc.iterCache.at(iter); - return offset; - } - - u32 offset = bc.engine_blob.add(iter.begin(), iter.end()); - - bc.iterCache.insert(make_pair(iter, offset)); - - return offset; -} - static u32 buildLastByteIter(const RoseGraph &g, build_context &bc) { vector lb_roles; @@ -2217,7 +2195,7 @@ u32 buildLastByteIter(const RoseGraph &g, build_context &bc) { vector iter; mmbBuildSparseIterator(iter, lb_roles, bc.numStates); - return addIteratorToTable(bc, iter); + return bc.engine_blob.add_iterator(iter); } static @@ -2329,7 +2307,7 @@ u32 buildEodNfaIterator(build_context &bc, const u32 activeQueueCount) { vector iter; mmbBuildSparseIterator(iter, keys, activeQueueCount); - return addIteratorToTable(bc, iter); + return bc.engine_blob.add_iterator(iter); } static @@ -4669,7 +4647,7 @@ u32 buildEagerQueueIter(const set &eager, u32 leftfixBeginQueue, vector iter; mmbBuildSparseIterator(iter, vec, queue_count - leftfixBeginQueue); - return addIteratorToTable(bc, iter); + return bc.engine_blob.add_iterator(iter); } static diff --git a/src/rose/rose_build_engine_blob.h b/src/rose/rose_build_engine_blob.h index 0914502e..8542b87b 100644 --- a/src/rose/rose_build_engine_blob.h +++ b/src/rose/rose_build_engine_blob.h @@ -34,6 +34,8 @@ #include "ue2common.h" #include "util/alloc.h" #include "util/container.h" +#include "util/multibit_build.h" +#include "util/ue2_containers.h" #include "util/verify_types.h" #include @@ -104,6 +106,19 @@ public: return offset; } + u32 add_iterator(const std::vector &iter) { + auto cache_it = cached_iters.find(iter); + if (cache_it != cached_iters.end()) { + u32 offset = cache_it->second; + DEBUG_PRINTF("cache hit for iter at %u\n", offset); + return offset; + } + + u32 offset = add(iter.begin(), iter.end()); + cached_iters.emplace(iter, offset); + return offset; + } + void write_bytes(RoseEngine *engine) { copy_bytes((char *)engine + base_offset, blob); } @@ -120,6 +135,9 @@ private: blob.resize(s + align - s % align); } + /** \brief Cache of previously-written sparse iterators. */ + unordered_map, u32> cached_iters; + /** * \brief Contents of the Rose bytecode immediately following the * RoseEngine. diff --git a/src/rose/rose_build_program.cpp b/src/rose/rose_build_program.cpp index 73740976..168022f3 100644 --- a/src/rose/rose_build_program.cpp +++ b/src/rose/rose_build_program.cpp @@ -387,7 +387,7 @@ void RoseInstrSparseIterBegin::write(void *dest, RoseEngineBlob &blob, vector iter; mmbBuildSparseIterator(iter, keys, num_keys); assert(!iter.empty()); - inst->iter_offset = blob.add(iter.begin(), iter.end()); + inst->iter_offset = blob.add_iterator(iter); inst->jump_table = blob.add(jump_offsets.begin(), jump_offsets.end()); // Store offsets for corresponding SPARSE_ITER_NEXT operations. @@ -422,7 +422,7 @@ void RoseInstrSparseIterAny::write(void *dest, RoseEngineBlob &blob, vector iter; mmbBuildSparseIterator(iter, keys, num_keys); assert(!iter.empty()); - inst->iter_offset = blob.add(iter.begin(), iter.end()); + inst->iter_offset = blob.add_iterator(iter); } void RoseInstrEnginesEod::write(void *dest, RoseEngineBlob &blob, diff --git a/src/util/multibit_build.h b/src/util/multibit_build.h index ac263552..5fbaab87 100644 --- a/src/util/multibit_build.h +++ b/src/util/multibit_build.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, Intel Corporation + * Copyright (c) 2015-2016, Intel Corporation * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: @@ -34,16 +34,18 @@ #define MULTIBIT_BUILD_H #include "multibit_internal.h" +#include "hash.h" #include -/** \brief Comparator for \ref mmbit_sparse_iter structures. */ -static inline -bool operator<(const mmbit_sparse_iter &a, const mmbit_sparse_iter &b) { - if (a.mask != b.mask) { - return a.mask < b.mask; - } - return a.val < b.val; +inline +bool operator==(const mmbit_sparse_iter &a, const mmbit_sparse_iter &b) { + return a.mask == b.mask && a.val == b.val; +} + +inline +size_t hash_value(const mmbit_sparse_iter &iter) { + return ue2::hash_all(iter.mask, iter.val); } namespace ue2 {