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; ...@@ -39,8 +39,8 @@ PyAPI_DATA(PyTypeObject*) generator_cls;
#define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type) #define PyGen_Check(op) PyObject_TypeCheck(op, &PyGen_Type)
#define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type) #define PyGen_CheckExact(op) (Py_TYPE(op) == &PyGen_Type)
PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *); PyAPI_FUNC(PyObject *) PyGen_New(struct _frame *) PYSTON_NOEXCEPT;
PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *); PyAPI_FUNC(int) PyGen_NeedsFinalizing(PyGenObject *) PYSTON_NOEXCEPT;
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -141,6 +141,8 @@ bool hasOrderedFinalizer(BoxedClass* cls) { ...@@ -141,6 +141,8 @@ bool hasOrderedFinalizer(BoxedClass* cls) {
} }
void finalize(Box* b) { void finalize(Box* b) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
GCAllocation* al = GCAllocation::fromUserData(b); GCAllocation* al = GCAllocation::fromUserData(b);
assert(!hasFinalized(al)); assert(!hasFinalized(al));
setFinalized(al); setFinalized(al);
...@@ -164,6 +166,8 @@ static StatCounter gc_safe_destructors("gc_safe_destructor_calls"); ...@@ -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, __attribute__((always_inline)) bool _doFree(GCAllocation* al, std::vector<Box*>* weakly_referenced,
std::vector<BoxedClass*>* classes_to_free) { std::vector<BoxedClass*>* classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
#ifndef NVALGRIND #ifndef NVALGRIND
VALGRIND_DISABLE_ERROR_REPORTING; VALGRIND_DISABLE_ERROR_REPORTING;
#endif #endif
...@@ -216,6 +220,8 @@ __attribute__((always_inline)) bool _doFree(GCAllocation* al, std::vector<Box*>* ...@@ -216,6 +220,8 @@ __attribute__((always_inline)) bool _doFree(GCAllocation* al, std::vector<Box*>*
} }
void Heap::destructContents(GCAllocation* al) { void Heap::destructContents(GCAllocation* al) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
_doFree(al, NULL, NULL); _doFree(al, NULL, NULL);
} }
...@@ -492,6 +498,8 @@ void SmallArena::forEachReference(std::function<void(GCAllocation*, size_t)> f) ...@@ -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) { void SmallArena::freeUnmarked(std::vector<Box*>& weakly_referenced, std::vector<BoxedClass*>& classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
assertConsistent(); assertConsistent();
thread_caches.forEachValue([this, &weakly_referenced, &classes_to_free](ThreadBlockCache* cache) { thread_caches.forEachValue([this, &weakly_referenced, &classes_to_free](ThreadBlockCache* cache) {
...@@ -559,6 +567,8 @@ void SmallArena::getStatistics(HeapStatistics* stats) { ...@@ -559,6 +567,8 @@ void SmallArena::getStatistics(HeapStatistics* stats) {
SmallArena::Block** SmallArena::_freeChain(Block** head, std::vector<Box*>& weakly_referenced, SmallArena::Block** SmallArena::_freeChain(Block** head, std::vector<Box*>& weakly_referenced,
std::vector<BoxedClass*>& classes_to_free) { std::vector<BoxedClass*>& classes_to_free) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
while (Block* b = *head) { while (Block* b = *head) {
int num_objects = b->numObjects(); int num_objects = b->numObjects();
int first_obj = b->minObjIndex(); int first_obj = b->minObjIndex();
...@@ -782,6 +792,8 @@ GCAllocation* LargeArena::realloc(GCAllocation* al, size_t bytes) { ...@@ -782,6 +792,8 @@ GCAllocation* LargeArena::realloc(GCAllocation* al, size_t bytes) {
} }
void LargeArena::free(GCAllocation* al) { void LargeArena::free(GCAllocation* al) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
_freeLargeObj(LargeObj::fromAllocation(al)); _freeLargeObj(LargeObj::fromAllocation(al));
} }
...@@ -828,6 +840,8 @@ void LargeArena::cleanupAfterCollection() { ...@@ -828,6 +840,8 @@ void LargeArena::cleanupAfterCollection() {
} }
void LargeArena::freeUnmarked(std::vector<Box*>& weakly_referenced, std::vector<BoxedClass*>& classes_to_free) { 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); }); sweepList(head, weakly_referenced, classes_to_free, [this](LargeObj* ptr) { _freeLargeObj(ptr); });
} }
...@@ -938,6 +952,8 @@ retry: ...@@ -938,6 +952,8 @@ retry:
} }
void LargeArena::_freeLargeObj(LargeObj* obj) { void LargeArena::_freeLargeObj(LargeObj* obj) {
RELEASE_ASSERT(0, "shouldn't do any gcs");
removeFromLL(obj); removeFromLL(obj);
size_t size = obj->size; size_t size = obj->size;
......
...@@ -1636,6 +1636,10 @@ extern "C" PyObject* PyMethod_Class(PyObject* im) noexcept { ...@@ -1636,6 +1636,10 @@ extern "C" PyObject* PyMethod_Class(PyObject* im) noexcept {
return ((BoxedInstanceMethod*)im)->im_class; return ((BoxedInstanceMethod*)im)->im_class;
} }
extern "C" int PyMethod_ClearFreeList(void) noexcept {
Py_FatalError("unimplemented");
}
void setupClassobj() { void setupClassobj() {
classobj_cls = BoxedClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs), classobj_cls = BoxedClass::create(type_cls, object_cls, &BoxedClassobj::gcHandler, offsetof(BoxedClassobj, attrs),
offsetof(BoxedClassobj, weakreflist), sizeof(BoxedClassobj), false, "classobj"); offsetof(BoxedClassobj, weakreflist), sizeof(BoxedClassobj), false, "classobj");
......
...@@ -792,6 +792,32 @@ void BoxedDict::dealloc(Box* b) noexcept { ...@@ -792,6 +792,32 @@ void BoxedDict::dealloc(Box* b) noexcept {
static_cast<BoxedDict*>(b)->d.freeAllMemory(); 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() { void setupDict() {
static PyMappingMethods dict_as_mapping; static PyMappingMethods dict_as_mapping;
dict_cls->tp_as_mapping = &dict_as_mapping; dict_cls->tp_as_mapping = &dict_as_mapping;
......
...@@ -477,6 +477,27 @@ void generatorDestructor(Box* b) { ...@@ -477,6 +477,27 @@ void generatorDestructor(Box* b) {
freeGeneratorStack(self); 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() { void setupGenerator() {
generator_cls generator_cls
= BoxedClass::create(type_cls, object_cls, &BoxedGenerator::gcHandler, 0, offsetof(BoxedGenerator, weakreflist), = BoxedClass::create(type_cls, object_cls, &BoxedGenerator::gcHandler, 0, offsetof(BoxedGenerator, weakreflist),
......
...@@ -654,6 +654,32 @@ static Box* tuple_getnewargs(Box* _self) noexcept { ...@@ -654,6 +654,32 @@ static Box* tuple_getnewargs(Box* _self) noexcept {
return Py_BuildValue("(N)", tupleslice(v, 0, Py_SIZE(v))); 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() { void setupTuple() {
static PySequenceMethods tuple_as_sequence; static PySequenceMethods tuple_as_sequence;
tuple_cls->tp_as_sequence = &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