Commit d48961f6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Update isValidGCObject to check the allocation kind

ie make sure both that it's a valid allocation, but also that
it will have Python destructor semantics applied when it is freed
(as opposed to, say, STLCompatAllocator-allocated memory).

This is to make sure that extension modules don't use a different
allocation routine than we expected.

There are only a few specialized places that I could find that we
actually want the old-behavior; in dump(), and in PyObject_Init right
before we call setIsPythonObject.  So for those cases, add a new
isValidGCMemory call that doesn't do the allocation-kind check.
parent cb7533ae
......@@ -180,10 +180,19 @@ bool isNonheapRoot(void* p) {
return nonheap_roots.count(p) != 0;
}
bool isValidGCObject(void* p) {
bool isValidGCMemory(void* p) {
return isNonheapRoot(p) || (global_heap.getAllocationFromInteriorPointer(p)->user_data == p);
}
bool isValidGCObject(void* p) {
if (isNonheapRoot(p))
return true;
GCAllocation* al = global_heap.getAllocationFromInteriorPointer(p);
if (!al)
return false;
return al->user_data == p && (al->kind_id == GCKind::CONSERVATIVE_PYTHON || al->kind_id == GCKind::PYTHON);
}
void setIsPythonObject(Box* b) {
auto al = global_heap.getAllocationFromInteriorPointer(b);
assert(al->user_data == (char*)b);
......
......@@ -60,7 +60,8 @@ void disableGC();
void enableGC();
// These are mostly for debugging:
bool isValidGCObject(void* p);
bool isValidGCMemory(void* p); // if p is a valid gc-allocated pointer (or a non-heap root)
bool isValidGCObject(void* p); // whether p is valid gc memory and is set to have Python destructor semantics applied
bool isNonheapRoot(void* p);
void setIsPythonObject(Box* b);
......
......@@ -1645,7 +1645,7 @@ static Box* methodGetDoc(Box* b, void*) {
extern "C" PyObject* _PyObject_GC_Malloc(size_t basicsize) noexcept {
Box* r = ((PyObject*)PyObject_MALLOC(basicsize));
RELEASE_ASSERT(gc::isValidGCObject(r), "");
RELEASE_ASSERT(gc::isValidGCMemory(r), "");
return r;
}
......
......@@ -2338,7 +2338,7 @@ extern "C" void dumpEx(void* p, int levels) {
printf("\n");
printf("Raw address: %p\n", p);
bool is_gc = gc::isValidGCObject(p);
bool is_gc = gc::isValidGCMemory(p);
if (!is_gc) {
printf("non-gc memory\n");
return;
......
......@@ -2233,11 +2233,11 @@ inline void initUserAttrs(Box* obj, BoxedClass* cls) {
extern "C" void PyCallIter_AddHasNext();
extern "C" PyVarObject* PyObject_InitVar(PyVarObject* op, PyTypeObject* tp, Py_ssize_t size) noexcept {
assert(gc::isValidGCObject(op));
assert(gc::isValidGCObject(tp));
assert(op);
assert(tp);
RELEASE_ASSERT(op, "");
RELEASE_ASSERT(tp, "");
assert(gc::isValidGCMemory(op));
assert(gc::isValidGCObject(tp));
gc::setIsPythonObject(op);
......@@ -2251,7 +2251,7 @@ extern "C" PyObject* PyObject_Init(PyObject* op, PyTypeObject* tp) noexcept {
assert(op);
assert(tp);
assert(gc::isValidGCObject(op));
assert(gc::isValidGCMemory(op));
assert(gc::isValidGCObject(tp));
gc::setIsPythonObject(op);
......
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