Commit 8240ff64 authored by Kevin Modzelewski's avatar Kevin Modzelewski

more gc functions

parent 0eb28782
......@@ -462,6 +462,71 @@ int BoxedWrapperObject::traverse(Box* _self, visitproc visit, void *arg) noexcep
return 0;
}
void BoxedProperty::dealloc(Box* _self) noexcept {
BoxedProperty* self = static_cast<BoxedProperty*>(_self);
PyObject_GC_UnTrack(self);
Py_XDECREF(self->prop_get);
Py_XDECREF(self->prop_set);
Py_XDECREF(self->prop_del);
Py_XDECREF(self->prop_doc);
self->cls->tp_free(self);
}
int BoxedProperty::traverse(Box* _self, visitproc visit, void *arg) noexcept {
BoxedProperty* self = static_cast<BoxedProperty*>(_self);
Py_VISIT(self->prop_get);
Py_VISIT(self->prop_set);
Py_VISIT(self->prop_del);
Py_VISIT(self->prop_doc);
return 0;
}
void BoxedStaticmethod::dealloc(Box* _self) noexcept {
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
PyObject_GC_UnTrack(self);
Py_XDECREF(self->sm_callable);
self->cls->tp_free(self);
}
int BoxedStaticmethod::traverse(Box* _self, visitproc visit, void *arg) noexcept {
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
Py_VISIT(self->sm_callable);
return 0;
}
int BoxedStaticmethod::clear(Box* _self) noexcept {
BoxedStaticmethod* self = static_cast<BoxedStaticmethod*>(_self);
Py_CLEAR(self->sm_callable);
return 0;
}
void BoxedClassmethod::dealloc(Box* _self) noexcept {
BoxedClassmethod* self = static_cast<BoxedClassmethod*>(_self);
PyObject_GC_UnTrack(self);
Py_XDECREF(self->cm_callable);
self->cls->tp_free(self);
}
int BoxedClassmethod::traverse(Box* _self, visitproc visit, void *arg) noexcept {
BoxedClassmethod* self = static_cast<BoxedClassmethod*>(_self);
Py_VISIT(self->cm_callable);
return 0;
}
int BoxedClassmethod::clear(Box* _self) noexcept {
BoxedClassmethod* self = static_cast<BoxedClassmethod*>(_self);
Py_CLEAR(self->cm_callable);
return 0;
}
Box* BoxedWrapperDescriptor::descr_get(Box* _self, Box* inst, Box* owner) noexcept {
STAT_TIMER(t0, "us_timer_boxedwrapperdescriptor_descr_get", 20);
......
......@@ -374,13 +374,27 @@ extern "C" int PySet_Add(PyObject* set, PyObject* key) noexcept {
}
Box* setClear(BoxedSet* self, Box* v) {
RELEASE_ASSERT(isSubclass(self->cls, set_cls), "");
Box* setClearInternal(BoxedSet* self) {
ASSERT(isSubclass(self->cls, set_cls), "");
RELEASE_ASSERT(0, "refcounting");
BoxedSet::Set tmp;
std::swap(tmp, self->s);
for (auto p : tmp) {
Py_DECREF(p.value);
}
self->s.clear();
return None;
}
Box* setClear(BoxedSet* self) {
RELEASE_ASSERT(isSubclass(self->cls, set_cls), "");
setClearInternal(self);
Py_RETURN_NONE;
}
extern "C" int PySet_Clear(PyObject* set) noexcept {
if (!PySet_Check(set)) {
PyErr_BadInternalCall();
......@@ -785,13 +799,38 @@ done:
} // namespace set
void BoxedSet::dealloc(Box* b) noexcept {
using namespace pyston::set;
void BoxedSet::dealloc(Box* _o) noexcept {
BoxedSet* o = (BoxedSet*)_o;
for (auto p : o->s) {
Py_DECREF(p.value);
}
// Unfortunately, this assert requires accessing the type object, which might have been freed already:
// assert(PyAnySet_Check(b));
static_cast<BoxedSet*>(b)->s.freeAllMemory();
o->s.freeAllMemory();
o->cls->tp_free(o);
}
using namespace pyston::set;
int BoxedSet::traverse(Box* _o, visitproc visit, void* arg) noexcept {
BoxedSet* o = (BoxedSet*)_o;
for (auto p : o->s) {
Py_VISIT(p.value);
}
return 0;
}
int BoxedSet::clear(Box* _o) noexcept {
BoxedSet* o = (BoxedSet*)_o;
setClearInternal(o);
return 0;
}
static PyMethodDef set_methods[] = {
{ "__reduce__", (PyCFunction)set_reduce, METH_NOARGS, NULL },
......
......@@ -38,6 +38,8 @@ public:
DEFAULT_CLASS(set_cls);
static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept;
static int clear(Box* self) noexcept;
};
}
......
......@@ -3535,6 +3535,36 @@ int HCAttrs::traverse(visitproc visit, void* arg) noexcept {
Py_FatalError("unimplemented");
}
void BoxedClosure::dealloc(Box* _o) noexcept {
BoxedClosure* o = (BoxedClosure*)_o;
for (int i = 0; i < o->nelts; i++) {
Py_XDECREF(o->elts[i]);
}
o->cls->tp_free(o);
}
int BoxedClosure::traverse(Box* _o, visitproc visit, void* arg) noexcept {
BoxedClosure* o = (BoxedClosure*)_o;
for (int i = 0; i < o->nelts; i++) {
Py_XDECREF(o->elts[i]);
}
return 0;
}
int BoxedClosure::clear(Box* _o) noexcept {
BoxedClosure* o = (BoxedClosure*)_o;
for (int i = 0; i < o->nelts; i++) {
Py_CLEAR(o->elts[i]);
}
return 0;
}
#ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS()
#else /* Py_REF_DEBUG */
......@@ -3769,20 +3799,23 @@ void setupRuntime() {
slice_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedSlice), false, "slice", BoxedSlice::dealloc, NULL, false);
set_cls = BoxedClass::create(type_cls, object_cls, 0, offsetof(BoxedSet, weakreflist),
sizeof(BoxedSet), false, "set");
frozenset_cls = BoxedClass::create(type_cls, object_cls, 0, offsetof(BoxedSet, weakreflist),
sizeof(BoxedSet), false, "frozenset");
capi_getset_cls
= BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset");
set_cls = BoxedClass::create(type_cls, object_cls, 0, offsetof(BoxedSet, weakreflist), sizeof(BoxedSet), false,
"set", BoxedSet::dealloc, NULL, true, BoxedSet::traverse, BoxedSet::clear);
frozenset_cls
= BoxedClass::create(type_cls, object_cls, 0, offsetof(BoxedSet, weakreflist), sizeof(BoxedSet), false,
"frozenset", BoxedSet::dealloc, NULL, true, BoxedSet::traverse, BoxedSet::clear);
capi_getset_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedGetsetDescriptor), false, "getset",
NULL, NULL, false);
closure_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedClosure), false,
"closure");
"closure", BoxedClosure::dealloc, NULL, true, BoxedClosure::traverse, BoxedClosure::clear);
property_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedProperty),
false, "property");
staticmethod_cls = BoxedClass::create(type_cls, object_cls, 0, 0,
sizeof(BoxedStaticmethod), false, "staticmethod");
classmethod_cls = BoxedClass::create(type_cls, object_cls, 0, 0,
sizeof(BoxedClassmethod), false, "classmethod");
false, "property", BoxedProperty::dealloc, NULL, true, BoxedProperty::traverse, NOCLEAR);
staticmethod_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedStaticmethod), false, "staticmethod",
BoxedStaticmethod::dealloc, NULL, true, BoxedStaticmethod::traverse,
BoxedStaticmethod::clear);
classmethod_cls = BoxedClass::create(type_cls, object_cls, 0, 0, sizeof(BoxedClassmethod), false, "classmethod",
BoxedClassmethod::dealloc, NULL, true, BoxedClassmethod::traverse,
BoxedClassmethod::clear);
attrwrapperiter_cls = BoxedClass::create(type_cls, object_cls, 0, 0,
sizeof(AttrWrapperIter), false, "attrwrapperiter");
......
......@@ -998,6 +998,9 @@ public:
BoxedProperty(Box* get, Box* set, Box* del, Box* doc)
: prop_get(get), prop_set(set), prop_del(del), prop_doc(doc) {}
static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept;
DEFAULT_CLASS_SIMPLE(property_cls, true);
};
......@@ -1008,6 +1011,10 @@ public:
BoxedStaticmethod(Box* callable) : sm_callable(callable){};
DEFAULT_CLASS_SIMPLE(staticmethod_cls, true);
static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept;
static int clear(Box* self) noexcept;
};
class BoxedClassmethod : public Box {
......@@ -1017,6 +1024,10 @@ public:
BoxedClassmethod(Box* callable) : cm_callable(callable){};
DEFAULT_CLASS_SIMPLE(classmethod_cls, true);
static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept;
static int clear(Box* self) noexcept;
};
// TODO is there any particular reason to make this a Box, i.e. a python-level object?
......@@ -1041,6 +1052,10 @@ public:
memset((void*)rtn->elts, 0, sizeof(Box*) * nelts);
return rtn;
}
static void dealloc(Box* b) noexcept;
static int traverse(Box* self, visitproc visit, void *arg) noexcept;
static int clear(Box* self) noexcept;
};
class BoxedGenerator : public Box {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment