store cached compiled code on alias stack

this will reduce needless discards on push and simplify the code
master
Daniel Kolesa 2021-04-02 02:11:38 +02:00
parent 2b0392e27e
commit 9d7853a840
3 changed files with 15 additions and 35 deletions

View File

@ -72,7 +72,7 @@ alias_impl::alias_impl(
state &cs, string_ref name, string_ref a, int fl
):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s.set_str(a);
}
@ -81,35 +81,35 @@ alias_impl::alias_impl(
state &cs, string_ref name, std::string_view a, int fl
):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s.set_str(a);
}
alias_impl::alias_impl(state &cs, string_ref name, integer_type a, int fl):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s.set_int(a);
}
alias_impl::alias_impl(state &cs, string_ref name, float_type a, int fl):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s.set_float(a);
}
alias_impl::alias_impl(state &cs, string_ref name, int fl):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s.set_none();
}
alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl):
ident_impl{ident_type::ALIAS, name, fl},
p_initial{cs}, p_acode{}, p_astack{&p_initial}
p_initial{cs}, p_astack{&p_initial}
{
p_initial.val_s = v;
}
@ -117,7 +117,6 @@ alias_impl::alias_impl(state &cs, string_ref name, any_value v, int fl):
void alias_impl::push_arg(ident_stack &st, bool um) {
st.next = p_astack;
p_astack = &st;
clean_code();
if (um) {
p_flags &= ~IDENT_FLAG_UNKNOWN;
}
@ -128,27 +127,20 @@ void alias_impl::pop_arg() {
return;
}
p_astack = p_astack->next;
clean_code();
}
void alias_impl::undo_arg(ident_stack &st) {
if (p_acode) {
st.val_s.set_code(p_acode);
}
st.next = p_astack;
p_astack = p_astack->next;
clean_code();
}
void alias_impl::redo_arg(ident_stack &st) {
p_astack = st.next;
clean_code();
p_acode = st.val_s.get_code();
}
void alias_impl::set_arg(thread_state &ts, any_value &v) {
if (ident_is_used_arg(this, ts)) {
clean_code();
p_astack->code = bcode_ref{};
} else {
push_arg(ts.idstack.emplace_back(*ts.pstate), false);
ts.callstack->usedargs[get_index()] = true;
@ -158,25 +150,21 @@ void alias_impl::set_arg(thread_state &ts, any_value &v) {
void alias_impl::set_alias(thread_state &ts, any_value &v) {
p_astack->val_s = std::move(v);
clean_code();
p_astack->code = bcode_ref{};
p_flags = (p_flags & ts.pstate->identflags) | ts.pstate->identflags;
}
void alias_impl::clean_code() {
p_acode = bcode_ref{};
}
bcode_ref const &alias_impl::compile_code(thread_state &ts) {
if (!p_acode) {
if (!p_astack->code) {
codegen_state gs(ts);
gs.code.reserve(64);
gs.gen_main(p_astack->val_s.get_str());
/* i wish i could steal the memory somehow */
uint32_t *code = bcode_alloc(ts.istate, gs.code.size());
memcpy(code, gs.code.data(), gs.code.size() * sizeof(uint32_t));
p_acode = bcode_ref{reinterpret_cast<bcode *>(code + 1)};
p_astack->code = bcode_ref{reinterpret_cast<bcode *>(code + 1)};
}
return p_acode;
return p_astack->code;
}
command_impl::command_impl(

View File

@ -18,8 +18,9 @@ enum {
struct ident_stack {
any_value val_s;
bcode_ref code;
ident_stack *next;
ident_stack(state &cs): val_s{cs}, next{nullptr} {}
ident_stack(state &cs): val_s{cs}, code{}, next{nullptr} {}
};
struct ident_link {
@ -102,11 +103,9 @@ struct alias_impl: ident_impl, alias {
void set_arg(thread_state &ts, any_value &v);
void set_alias(thread_state &ts, any_value &v);
void clean_code();
bcode_ref const &compile_code(thread_state &ts);
ident_stack p_initial;
bcode_ref p_acode;
ident_stack *p_astack;
};

View File

@ -193,14 +193,7 @@ LIBCUBESCRIPT_EXPORT void state::destroy() {
}
auto *sp = p_tstate->istate;
for (auto &p: sp->idents) {
ident *i = p.second;
alias *a = i->get_alias();
if (a) {
auto *aimp = static_cast<alias_impl *>(a);
aimp->p_astack->val_s.force_none();
aimp->clean_code();
}
sp->destroy(i->p_impl);
sp->destroy(p.second->p_impl);
}
sp->destroy(p_tstate);
sp->destroy(sp);
@ -467,8 +460,8 @@ LIBCUBESCRIPT_EXPORT void state::clear_override(ident &id) {
switch (id.get_type()) {
case ident_type::ALIAS: {
alias_impl &a = static_cast<alias_impl &>(id);
a.clean_code();
a.p_astack->val_s.set_str("");
a.p_astack->code = bcode_ref{};
break;
}
case ident_type::IVAR: {