This enables its use for iterators written by instructions.
*/
size_t numStates = 0;
- /** \brief Very simple cache from sparse iter to offset, used when building
- * up iterators in early misc. */
- map<vector<mmbit_sparse_iter>, u32> iterCache;
-
/** \brief Simple cache of programs written to engine blob, used for
* deduplication. */
ue2::unordered_map<RoseProgram, u32, RoseProgramHash,
return m ? m - 1 : 0;
}
-// Adds a sparse iterator to the end of the iterator table, returning its
-// offset.
-static
-u32 addIteratorToTable(build_context &bc,
- const vector<mmbit_sparse_iter> &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<u32> lb_roles;
vector<mmbit_sparse_iter> iter;
mmbBuildSparseIterator(iter, lb_roles, bc.numStates);
- return addIteratorToTable(bc, iter);
+ return bc.engine_blob.add_iterator(iter);
}
static
vector<mmbit_sparse_iter> iter;
mmbBuildSparseIterator(iter, keys, activeQueueCount);
- return addIteratorToTable(bc, iter);
+ return bc.engine_blob.add_iterator(iter);
}
static
vector<mmbit_sparse_iter> iter;
mmbBuildSparseIterator(iter, vec, queue_count - leftfixBeginQueue);
- return addIteratorToTable(bc, iter);
+ return bc.engine_blob.add_iterator(iter);
}
static
#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 <vector>
return offset;
}
+ u32 add_iterator(const std::vector<mmbit_sparse_iter> &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);
}
blob.resize(s + align - s % align);
}
+ /** \brief Cache of previously-written sparse iterators. */
+ unordered_map<std::vector<mmbit_sparse_iter>, u32> cached_iters;
+
/**
* \brief Contents of the Rose bytecode immediately following the
* RoseEngine.
vector<mmbit_sparse_iter> 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.
vector<mmbit_sparse_iter> 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,
/*
- * 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:
#define MULTIBIT_BUILD_H
#include "multibit_internal.h"
+#include "hash.h"
#include <vector>
-/** \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 {