Manage GC data better

Make sure that all cdata references for variables is tracked. This is
done by attaching finalizers to Expression and Term objects. Some
effort is made to avoid creating tracked temporary objects (esp Terms)
now.
This commit is contained in:
2024-02-13 20:55:37 -06:00
parent e43272487f
commit 84a01179cd
3 changed files with 135 additions and 86 deletions

View File

@@ -10,7 +10,7 @@ using namespace kiwi;
namespace {
template<typename T, typename R, typename... Args>
inline R to_cref(Args&&... args) {
inline R make_cref(Args&&... args) {
static_assert(
sizeof(R) >= sizeof(T), //NOLINT(bugprone-sizeof-expression)
"to_cref: R too small for T"
@@ -23,13 +23,13 @@ inline R to_cref(Args&&... args) {
}
template<typename... Args>
inline decltype(auto) to_var_cref(Args&&... args) {
return to_cref<Variable, KiwiVarRef>(std::forward<Args>(args)...);
inline decltype(auto) make_var_cref(Args&&... args) {
return make_cref<Variable, KiwiVarRef>(std::forward<Args>(args)...);
}
template<typename... Args>
inline decltype(auto) to_constraint_cref(Args&&... args) {
return to_cref<Constraint, KiwiConstraintRef>(std::forward<Args>(args)...);
inline decltype(auto) make_constraint_cref(Args&&... args) {
return make_cref<Constraint, KiwiConstraintRef>(std::forward<Args>(args)...);
}
template<class T, class R>
@@ -45,7 +45,11 @@ class SharedRef {
"SharedRef<T,CS> CS too small for T"
);
void destroy() {
R clone() const {
return make_cref<T, R>(cref());
}
void release() {
if (cref_) {
ptr()->~T();
cref_ = nullptr;
@@ -201,11 +205,15 @@ inline KiwiErrPtr wrap_err(P ptr, R ref, F&& f) {
extern "C" {
KiwiVarRef kiwi_var_new(const char* name) {
return to_var_cref(name ? name : "");
return make_var_cref(name ? name : "");
}
void kiwi_var_del(KiwiVarRef var) {
VariableRef(var).destroy();
VariableRef(var).release();
}
KiwiVarRef kiwi_var_clone(KiwiVarRef var) {
return VariableRef(var).clone();
}
const char* kiwi_var_name(KiwiVarRef var) {
@@ -252,7 +260,7 @@ kiwi_constraint_new(KiwiExpressionConstPtr expression, enum KiwiRelOp op, double
terms.emplace_back(var.cref(), t->coefficient);
}
}
return to_constraint_cref(
return make_constraint_cref(
Expression(std::move(terms), expression->constant),
static_cast<RelationalOperator>(op),
strength
@@ -260,7 +268,11 @@ kiwi_constraint_new(KiwiExpressionConstPtr expression, enum KiwiRelOp op, double
}
void kiwi_constraint_del(KiwiConstraintRef constraint) {
ConstraintRef(constraint).destroy();
ConstraintRef(constraint).release();
}
KiwiConstraintRef kiwi_constraint_clone(KiwiConstraintRef constraint) {
return ConstraintRef(constraint).clone();
}
double kiwi_constraint_strength(KiwiConstraintRef constraint) {
@@ -290,7 +302,7 @@ int kiwi_constraint_expression(KiwiConstraintRef constraint, KiwiExpression* out
auto* p = out->terms;
for (const auto& t : terms) {
*p = KiwiTerm {to_var_cref(t.variable()), t.coefficient()};
*p = KiwiTerm {make_var_cref(t.variable()), t.coefficient()};
++p;
}
out->term_count = p - out->terms;