Commit 437a1468 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Bunch of fixes

gc now runs, though it can't free everything
parent df261ea5
......@@ -553,7 +553,6 @@ move_finalizers(PyGC_Head *unreachable, PyGC_Head *finalizers)
PyObject *op = FROM_GC(gc);
// Pyston addition: for now assert that the gc isn't freeing anything.
assert(0 && "something getting freed by the GC! check it out");
assert(IS_TENTATIVELY_UNREACHABLE(op));
next = gc->gc.gc_next;
......
......@@ -3416,6 +3416,11 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
BoxedClass* base = cls->tp_base;
if (base == NULL)
base = cls->tp_base = object_cls;
// CPython only increfs the base if it picked one, not if it one was passed in.
// Not sure why.
Py_INCREF(base);
if (!cls->cls)
cls->cls = cls->tp_base->cls;
cls->giveAttrBorrowed("__base__", base);
......
......@@ -194,6 +194,11 @@ extern "C" Py_ssize_t PyDict_Size(PyObject* op) noexcept {
}
extern "C" void PyDict_Clear(PyObject* op) noexcept {
if (op->cls == attrwrapper_cls) {
attrwrapperClear(op);
return;
}
RELEASE_ASSERT(PyDict_Check(op), "");
static_cast<BoxedDict*>(op)->d.clear();
}
......@@ -755,12 +760,17 @@ static Box* dict_repr(PyObject* self) noexcept {
}
void BoxedDict::dealloc(Box* b) noexcept {
if (_PyObject_GC_IS_TRACKED(b))
_PyObject_GC_UNTRACK(b);
assert(PyDict_Check(b));
for (auto p : *static_cast<BoxedDict*>(b)) {
Py_DECREF(p.first);
Py_DECREF(p.second);
}
static_cast<BoxedDict*>(b)->d.freeAllMemory();
b->cls->tp_free(b);
}
int BoxedDict::traverse(PyObject* op, visitproc visit, void* arg) noexcept {
......
......@@ -1273,7 +1273,7 @@ void BoxedList::dealloc(Box* b) noexcept {
while (--i >= 0) {
Py_XDECREF(op->elts->elts[i]);
}
//PyMem_FREE(op->elts);
delete op->elts;
}
#if 0
if (numfree < PyList_MAXFREELIST && PyList_CheckExact(op))
......@@ -1294,20 +1294,21 @@ int BoxedList::traverse(Box* _o, visitproc visit, void* arg) noexcept {
}
int BoxedList::clear(Box* _a) noexcept {
PyListObject* a = (PyListObject*)_a;
BoxedList* a = (BoxedList*)_a;
Py_ssize_t i;
PyObject **item = a->ob_item;
if (item != NULL) {
if (a->elts) {
PyObject **item = a->elts->elts;
/* Because XDECREF can recursively invoke operations on
this list, we make it empty first. */
i = Py_SIZE(a);
Py_SIZE(a) = 0;
a->ob_item = NULL;
a->allocated = 0;
a->capacity = 0;
auto old_elts = a->elts;
a->elts = NULL;
while (--i >= 0) {
Py_XDECREF(item[i]);
}
PyMem_FREE(item);
delete old_elts;
}
/* Never fails; the return value can be ignored.
Note that there is no guarantee that the list is actually empty
......
......@@ -446,6 +446,7 @@ BoxedClass::BoxedClass(BoxedClass* base, int attrs_offset, int weaklist_offset,
tp_flags |= Py_TPFLAGS_CHECKTYPES;
}
Py_XINCREF(base);
tp_base = base;
if (tp_base) {
......
......@@ -392,6 +392,7 @@ static void functionDtor(Box* b) {
assert(isSubclass(b->cls, function_cls) || isSubclass(b->cls, builtin_function_or_method_cls));
BoxedFunctionBase* self = static_cast<BoxedFunctionBase*>(b);
PyObject_GC_UnTrack(self);
self->dependent_ics.invalidateAll();
self->dependent_ics.~ICInvalidator();
......@@ -401,6 +402,8 @@ static void functionDtor(Box* b) {
Py_XDECREF(self->closure);
Py_XDECREF(self->globals);
Py_XDECREF(self->defaults);
self->cls->tp_free(self);
}
static int func_traverse(BoxedFunction* f, visitproc visit, void* arg) noexcept {
......@@ -2557,6 +2560,10 @@ void attrwrapperDel(Box* b, llvm::StringRef attr) {
AttrWrapper::delitem(b, boxString(attr));
}
void attrwrapperClear(Box* aw) {
AttrWrapper::clear(aw);
}
BoxedDict* attrwrapperToDict(Box* b) {
assert(b->cls == attrwrapper_cls);
Box* d = AttrWrapper::copy(static_cast<AttrWrapper*>(b));
......@@ -3426,15 +3433,24 @@ int BoxedInstanceMethod::traverse(Box* _im, visitproc visit, void* arg) noexcept
return 0;
}
bool IN_SHUTDOWN = false;
void BoxedClass::dealloc(Box* b) noexcept {
BoxedClass* type = static_cast<BoxedClass*>(b);
if (PyObject_IS_GC(type))
_PyObject_GC_UNTRACK(type);
type->clearAttrs();
Py_XDECREF(type->tp_dict);
Py_XDECREF(type->tp_bases);
Py_XDECREF(type->tp_subclasses);
//Py_XDECREF(type->tp_mro); // XXX was done manually
Py_XDECREF(type->tp_mro);
Py_XDECREF(type->tp_base);
// During shutdown, don't free class objects since that would make
// debugging very hard.
if (!IN_SHUTDOWN)
Py_TYPE(type)->tp_free(type);
// Copied in the CPython implementation for reference:
#if 0
......@@ -4093,21 +4109,25 @@ void setupRuntime() {
setupAST();
// XXX
PyGC_Collect(); // To make sure it creates any static objects
IN_SHUTDOWN = true;
PyType_ClearCache();
_Py_ReleaseInternedStrings();
_PyUnicode_Fini();
for (auto b : classes)
for (auto b : classes) {
b->clearAttrs();
if (!PyObject_IS_GC(b)) {
Py_CLEAR(b->tp_mro);
}
}
for (auto b : constants) {
b->clearAttrs();
Py_DECREF(b);
}
for (auto b : classes) {
if (b->tp_mro) {
Py_DECREF(b->tp_mro);
}
Py_DECREF(b);
}
PyGC_Collect();
PRINT_TOTAL_REFS();
exit(0);
// XXX
......
......@@ -528,7 +528,7 @@ public:
GCdArray* elts;
Py_ssize_t capacity;
BoxedList() __attribute__((visibility("default"))) : size(0), capacity(0) {}
BoxedList() __attribute__((visibility("default"))) : size(0), elts(NULL), capacity(0) {}
void ensure(int min_free);
void shrink();
......@@ -697,6 +697,7 @@ public:
BoxVar* rtn = static_cast<BoxVar*>(PyObject_GC_NewVar(BoxedTuple, &PyTuple_Type, nitems));
assert(rtn);
_PyObject_GC_TRACK(rtn);
return rtn;
}
......@@ -1154,6 +1155,7 @@ Box* objectSetattr(Box* obj, Box* attr, Box* value);
Box* unwrapAttrWrapper(Box* b);
Box* attrwrapperKeys(Box* b);
void attrwrapperDel(Box* b, llvm::StringRef attr);
void attrwrapperClear(Box* b);
BoxedDict* attrwrapperToDict(Box* b);
Box* boxAst(AST* ast);
......
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