Commit 0448afc9 authored by Kevin Modzelewski's avatar Kevin Modzelewski

some stuff the cycle collector wants

parent 751f2ac4
......@@ -39,8 +39,8 @@ PyAPI_DATA(PyTypeObject*) generator_cls;
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type)
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *);
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *);
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *) PYSTON_NOEXCEPT;
#ifdef __cplusplus
}
......
......@@ -141,6 +141,8 @@ bool hasOrderedFinalizer(BoxedClass* cls) {
}
void finalize(Box* b) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
GCAllocation* al = GCAllocation::fromUserData(b);
assert(!hasFinalized(al));
setFinalized(al);
......@@ -164,6 +166,8 @@ static StatCounter gc_safe_destructors("gc_safe_destructor_calls");
__attribute__((always_inline)) bool _doFree(GCAllocation* al, std::vector<Box*>* weakly_referenced,
std::vector<BoxedClass*>* classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
#ifndef NVALGRIND
VALGRIND_DISABLE_ERROR_REPORTING;
#endif
......@@ -216,6 +220,8 @@ __attribute__((always_inline)) bool _doFree(GCAllocation* al, std::vector<Box*>*
}
void Heap::destructContents(GCAllocation* al) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
_doFree(al, NULL, NULL);
}
......@@ -492,6 +498,8 @@ void SmallArena::forEachReference(std::function<void(GCAllocation*, size_t)> f)
}
void SmallArena::freeUnmarked(std::vector<Box*>& weakly_referenced, std::vector<BoxedClass*>& classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
assertConsistent();
thread_caches.forEachValue([this, &weakly_referenced, &classes_to_free](ThreadBlockCache* cache) {
......@@ -559,6 +567,8 @@ void SmallArena::getStatistics(HeapStatistics* stats) {
SmallArena::Block** SmallArena::_freeChain(Block** head, std::vector<Box*>& weakly_referenced,
std::vector<BoxedClass*>& classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
while (Block* b = *head) {
int num_objects = b->numObjects();
int first_obj = b->minObjIndex();
......@@ -782,6 +792,8 @@ GCAllocation* LargeArena::realloc(GCAllocation* al, size_t bytes) {
}
void LargeArena::free(GCAllocation* al) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
_freeLargeObj(LargeObj::fromAllocation(al));
}
......@@ -828,6 +840,8 @@ void LargeArena::cleanupAfterCollection() {
}
void LargeArena::freeUnmarked(std::vector<Box*>& weakly_referenced, std::vector<BoxedClass*>& classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
sweepList(head, weakly_referenced, classes_to_free, [this](LargeObj* ptr) { _freeLargeObj(ptr); });
}
......@@ -938,6 +952,8 @@ retry:
}
void LargeArena::_freeLargeObj(LargeObj* obj) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
removeFromLL(obj);
size_t size = obj->size;
......
......@@ -1636,6 +1636,10 @@ extern "C" PyObject* PyMethod_Class(PyObject* im) noexcept {
return ((BoxedInstanceMethod*)im)->im_class;
}
extern "C" int PyMethod_ClearFreeList(void) noexcept {
Py_FatalError("unimplemented");
}
void setupClassobj() {
classobj_cls = BoxedClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
offsetof(BoxedClassobj, weakreflist), sizeof(BoxedClassobj), false, "classobj");
......
......@@ -792,6 +792,32 @@ void BoxedDict::dealloc(Box* b) noexcept {
static_cast<BoxedDict*>(b)->d.freeAllMemory();
}
extern "C" void _PyDict_MaybeUntrack(PyObject* op) noexcept {
PyDictObject* mp;
PyObject* value;
Py_ssize_t mask, i;
if (!PyDict_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
return;
Py_FatalError("unimplemented");
/*
PyDictEntry* ep;
mp = (PyDictObject *) op;
ep = mp->ma_table;
mask = mp->ma_mask;
for (i = 0; i <= mask; i++) {
if ((value = ep[i].me_value) == NULL)
continue;
if (_PyObject_GC_MAY_BE_TRACKED(value) ||
_PyObject_GC_MAY_BE_TRACKED(ep[i].me_key))
return;
}
DECREASE_TRACK_COUNT
_PyObject_GC_UNTRACK(op);
*/
}
void setupDict() {
static PyMappingMethods dict_as_mapping;
dict_cls->tp_as_mapping = &dict_as_mapping;
......
......@@ -477,6 +477,27 @@ void generatorDestructor(Box* b) {
freeGeneratorStack(self);
}
extern "C" int PyGen_NeedsFinalizing(PyGenObject* gen) noexcept {
Py_FatalError("unimplemented");
#if 0
int i;
PyFrameObject* f = gen->gi_frame;
if (f == NULL || f->f_stacktop == NULL || f->f_iblock <= 0)
return 0; /* no frame or empty blockstack == no finalization */
/* Any block type besides a loop requires cleanup. */
i = f->f_iblock;
while (--i >= 0) {
if (f->f_blockstack[i].b_type != SETUP_LOOP)
return 1;
}
/* No blocks except loops, it's safe to skip finalization. */
return 0;
#endif
}
void setupGenerator() {
generator_cls
= BoxedClass::create(type_cls, object_cls, &BoxedGenerator::gcHandler, 0, offsetof(BoxedGenerator, weakreflist),
......
......@@ -654,6 +654,32 @@ static Box* tuple_getnewargs(Box* _self) noexcept {
return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v)));
}
extern "C" void
_PyTuple_MaybeUntrack(PyObject *op) noexcept
{
PyTupleObject *t;
Py_ssize_t i, n;
if (!PyTuple_CheckExact(op) || !_PyObject_GC_IS_TRACKED(op))
return;
t = (PyTupleObject *) op;
n = Py_SIZE(t);
for (i = 0; i < n; i++) {
PyObject *elt = PyTuple_GET_ITEM(t, i);
/* Tuple with NULL elements aren't
fully constructed, don't untrack
them yet. */
if (!elt ||
_PyObject_GC_MAY_BE_TRACKED(elt))
return;
}
#ifdef SHOW_TRACK_COUNT
count_tracked--;
count_untracked++;
#endif
_PyObject_GC_UNTRACK(op);
}
void setupTuple() {
static PySequenceMethods tuple_as_sequence;
tuple_cls->tp_as_sequence = &tuple_as_sequence;
......
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