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