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

View File

@ -18,8 +18,9 @@ enum {
struct ident_stack { struct ident_stack {
any_value val_s; any_value val_s;
bcode_ref code;
ident_stack *next; 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 { struct ident_link {
@ -102,11 +103,9 @@ struct alias_impl: ident_impl, alias {
void set_arg(thread_state &ts, any_value &v); void set_arg(thread_state &ts, any_value &v);
void set_alias(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); bcode_ref const &compile_code(thread_state &ts);
ident_stack p_initial; ident_stack p_initial;
bcode_ref p_acode;
ident_stack *p_astack; ident_stack *p_astack;
}; };

View File

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