lock-free argument lookup
Since we know these ids are always early and up to a fixed index, we can have a separate, fixed mapping for them, which is only initialized once during state creation, and never changes.
This commit is contained in:
parent
4627321e23
commit
2406324a96
|
@ -45,11 +45,17 @@ static void *default_alloc(void *, void *p, size_t, size_t ns) {
|
|||
}
|
||||
|
||||
ident *internal_state::lookup_ident(std::size_t idx) {
|
||||
if (idx < MAX_ARGUMENTS) {
|
||||
return argmap[idx];
|
||||
}
|
||||
std::lock_guard<std::mutex> l{ident_mtx};
|
||||
return identmap[idx];
|
||||
}
|
||||
|
||||
ident const *internal_state::lookup_ident(std::size_t idx) const {
|
||||
if (idx < MAX_ARGUMENTS) {
|
||||
return argmap[idx];
|
||||
}
|
||||
std::lock_guard<std::mutex> l{ident_mtx};
|
||||
return identmap[idx];
|
||||
}
|
||||
|
@ -141,7 +147,7 @@ state::state(alloc_func func, void *data) {
|
|||
for (std::size_t i = 0; i < MAX_ARGUMENTS; ++i) {
|
||||
char buf[16];
|
||||
snprintf(buf, sizeof(buf), "arg%zu", i + 1);
|
||||
statep->new_ident(
|
||||
statep->argmap[i] = &statep->new_ident(
|
||||
*this, static_cast<char const *>(buf), IDENT_FLAG_ARG
|
||||
);
|
||||
}
|
||||
|
|
|
@ -50,6 +50,7 @@ struct internal_state {
|
|||
allocator_type
|
||||
> idents;
|
||||
std::vector<ident *, std_allocator<ident *>> identmap;
|
||||
std::array<ident *, MAX_ARGUMENTS> argmap;
|
||||
mutable std::mutex ident_mtx;
|
||||
|
||||
string_pool *strman;
|
||||
|
|
10
src/cs_vm.cc
10
src/cs_vm.cc
|
@ -133,7 +133,7 @@ any_value exec_alias(
|
|||
std::size_t noff = ts.idstack.size();
|
||||
for(std::size_t i = 0; i < callargs; i++) {
|
||||
auto &ast = ts.get_astack(
|
||||
static_cast<alias *>(ts.istate->lookup_ident(i))
|
||||
static_cast<alias *>(ts.istate->argmap[i])
|
||||
);
|
||||
auto &st = ts.idstack.emplace_back();
|
||||
ast.push(st);
|
||||
|
@ -167,14 +167,14 @@ any_value exec_alias(
|
|||
tss.ident_flags = oflags;
|
||||
for (std::size_t i = 0; i < cargs; i++) {
|
||||
tss.get_astack(
|
||||
static_cast<alias *>(tss.istate->lookup_ident(i))
|
||||
static_cast<alias *>(tss.istate->argmap[i])
|
||||
).pop();
|
||||
amask[i] = false;
|
||||
}
|
||||
for (; amask.any(); ++cargs) {
|
||||
if (amask[cargs]) {
|
||||
tss.get_astack(
|
||||
static_cast<alias *>(tss.istate->lookup_ident(cargs))
|
||||
static_cast<alias *>(tss.istate->argmap[cargs])
|
||||
).pop();
|
||||
amask[cargs] = false;
|
||||
}
|
||||
|
@ -202,7 +202,7 @@ any_value exec_code_with_args(thread_state &ts, bcode_ref const &body) {
|
|||
for (std::size_t i = 0; mask.any(); ++i) {
|
||||
if (mask[0]) {
|
||||
auto &ast = ts.get_astack(
|
||||
static_cast<alias *>(ts.istate->lookup_ident(i))
|
||||
static_cast<alias *>(ts.istate->argmap[i])
|
||||
);
|
||||
auto &st = ts.idstack.emplace_back();
|
||||
st.next = ast.node;
|
||||
|
@ -229,7 +229,7 @@ any_value exec_code_with_args(thread_state &ts, bcode_ref const &body) {
|
|||
for (std::size_t i = 0, nredo = 0; mask2.any(); ++i) {
|
||||
if (mask2[0]) {
|
||||
tss.get_astack(
|
||||
static_cast<alias *>(tss.istate->lookup_ident(i))
|
||||
static_cast<alias *>(tss.istate->argmap[i])
|
||||
).node = tss.idstack[offn + nredo++].next;
|
||||
}
|
||||
mask2 >>= 1;
|
||||
|
|
Loading…
Reference in a new issue