Commit 8237d41d authored by Kevin Modzelewski's avatar Kevin Modzelewski

More refcount fixes

parent dc4d003b
...@@ -126,9 +126,9 @@ PyAPI_FUNC(int) PyObject_TraverseHcAttrs(PyHcAttrs*, visitproc visit, void* arg) ...@@ -126,9 +126,9 @@ PyAPI_FUNC(int) PyObject_TraverseHcAttrs(PyHcAttrs*, visitproc visit, void* arg)
PyAPI_FUNC(void) PyType_SetDict(PyTypeObject*, PyObject*) PYSTON_NOEXCEPT; PyAPI_FUNC(void) PyType_SetDict(PyTypeObject*, PyObject*) PYSTON_NOEXCEPT;
// Pyston addition: register an object as a "static constant". Current purpose is that this will // Pyston addition: register an object as a "static constant". Current purpose is that this will
// get decref'd when the interpreter shuts down. // get decref'd when the interpreter shuts down. This functions returns its argument.
// PyType_Ready calls this automatically. // PyType_Ready calls this automatically.
PyAPI_FUNC(void) PyGC_RegisterStaticConstant(PyObject*) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject*) PyGC_RegisterStaticConstant(PyObject*) PYSTON_NOEXCEPT;
// Pyston addition: // Pyston addition:
PyAPI_FUNC(void) PyGC_Enable() PYSTON_NOEXCEPT; PyAPI_FUNC(void) PyGC_Enable() PYSTON_NOEXCEPT;
......
...@@ -1625,5 +1625,10 @@ init_csv(void) ...@@ -1625,5 +1625,10 @@ init_csv(void)
error_obj = PyErr_NewException("_csv.Error", NULL, NULL); error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
if (error_obj == NULL) if (error_obj == NULL)
return; return;
// Pyston change: I *think* an incref is needed here, but it doesn't matter in CPython since they don't
// try to tear down builtin classes:
Py_INCREF(error_obj);
PyModule_AddObject(module, "Error", error_obj); PyModule_AddObject(module, "Error", error_obj);
} }
...@@ -712,63 +712,61 @@ init_io(void) ...@@ -712,63 +712,61 @@ init_io(void)
/* IncrementalNewlineDecoder */ /* IncrementalNewlineDecoder */
ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder"); ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder");
// Pyston change: register with gc
// TODO: automatically register static variables as roots
/* Interned strings */ /* Interned strings */
// Pyston change: these are no longered interned since the interned-ness wasn't being relied on, // Pyston change: these are no longered interned since the interned-ness wasn't being relied on,
// and we don't yet support real on-demand interning. // and we don't yet support real on-demand interning.
if (!(_PyIO_str_close = PyString_FromString("close"))) if (!(_PyIO_str_close = PyGC_RegisterStaticConstant(PyString_InternFromString("close"))))
goto fail; goto fail;
if (!(_PyIO_str_closed = PyString_FromString("closed"))) if (!(_PyIO_str_closed = PyGC_RegisterStaticConstant(PyString_InternFromString("closed"))))
goto fail; goto fail;
if (!(_PyIO_str_decode = PyString_FromString("decode"))) if (!(_PyIO_str_decode = PyGC_RegisterStaticConstant(PyString_InternFromString("decode"))))
goto fail; goto fail;
if (!(_PyIO_str_encode = PyString_FromString("encode"))) if (!(_PyIO_str_encode = PyGC_RegisterStaticConstant(PyString_InternFromString("encode"))))
goto fail; goto fail;
if (!(_PyIO_str_fileno = PyString_FromString("fileno"))) if (!(_PyIO_str_fileno = PyGC_RegisterStaticConstant(PyString_InternFromString("fileno"))))
goto fail; goto fail;
if (!(_PyIO_str_flush = PyString_FromString("flush"))) if (!(_PyIO_str_flush = PyGC_RegisterStaticConstant(PyString_InternFromString("flush"))))
goto fail; goto fail;
if (!(_PyIO_str_getstate = PyString_FromString("getstate"))) if (!(_PyIO_str_getstate = PyGC_RegisterStaticConstant(PyString_InternFromString("getstate"))))
goto fail; goto fail;
if (!(_PyIO_str_isatty = PyString_FromString("isatty"))) if (!(_PyIO_str_isatty = PyGC_RegisterStaticConstant(PyString_InternFromString("isatty"))))
goto fail; goto fail;
if (!(_PyIO_str_newlines = PyString_FromString("newlines"))) if (!(_PyIO_str_newlines = PyGC_RegisterStaticConstant(PyString_InternFromString("newlines"))))
goto fail; goto fail;
if (!(_PyIO_str_nl = PyString_FromString("\n"))) if (!(_PyIO_str_nl = PyGC_RegisterStaticConstant(PyString_InternFromString("\n"))))
goto fail; goto fail;
if (!(_PyIO_str_read = PyString_FromString("read"))) if (!(_PyIO_str_read = PyGC_RegisterStaticConstant(PyString_InternFromString("read"))))
goto fail; goto fail;
if (!(_PyIO_str_read1 = PyString_FromString("read1"))) if (!(_PyIO_str_read1 = PyGC_RegisterStaticConstant(PyString_InternFromString("read1"))))
goto fail; goto fail;
if (!(_PyIO_str_readable = PyString_FromString("readable"))) if (!(_PyIO_str_readable = PyGC_RegisterStaticConstant(PyString_InternFromString("readable"))))
goto fail; goto fail;
if (!(_PyIO_str_readinto = PyString_FromString("readinto"))) if (!(_PyIO_str_readinto = PyGC_RegisterStaticConstant(PyString_InternFromString("readinto"))))
goto fail; goto fail;
if (!(_PyIO_str_readline = PyString_FromString("readline"))) if (!(_PyIO_str_readline = PyGC_RegisterStaticConstant(PyString_InternFromString("readline"))))
goto fail; goto fail;
if (!(_PyIO_str_reset = PyString_FromString("reset"))) if (!(_PyIO_str_reset = PyGC_RegisterStaticConstant(PyString_InternFromString("reset"))))
goto fail; goto fail;
if (!(_PyIO_str_seek = PyString_FromString("seek"))) if (!(_PyIO_str_seek = PyGC_RegisterStaticConstant(PyString_InternFromString("seek"))))
goto fail; goto fail;
if (!(_PyIO_str_seekable = PyString_FromString("seekable"))) if (!(_PyIO_str_seekable = PyGC_RegisterStaticConstant(PyString_InternFromString("seekable"))))
goto fail; goto fail;
if (!(_PyIO_str_setstate = PyString_FromString("setstate"))) if (!(_PyIO_str_setstate = PyGC_RegisterStaticConstant(PyString_InternFromString("setstate"))))
goto fail; goto fail;
if (!(_PyIO_str_tell = PyString_FromString("tell"))) if (!(_PyIO_str_tell = PyGC_RegisterStaticConstant(PyString_InternFromString("tell"))))
goto fail; goto fail;
if (!(_PyIO_str_truncate = PyString_FromString("truncate"))) if (!(_PyIO_str_truncate = PyGC_RegisterStaticConstant(PyString_InternFromString("truncate"))))
goto fail; goto fail;
if (!(_PyIO_str_write = PyString_FromString("write"))) if (!(_PyIO_str_write = PyGC_RegisterStaticConstant(PyString_InternFromString("write"))))
goto fail; goto fail;
if (!(_PyIO_str_writable = PyString_FromString("writable"))) if (!(_PyIO_str_writable = PyGC_RegisterStaticConstant(PyString_InternFromString("writable"))))
goto fail; goto fail;
if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0))) if (!(_PyIO_empty_str = PyGC_RegisterStaticConstant(PyUnicode_FromStringAndSize(NULL, 0))))
goto fail; goto fail;
if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0))) if (!(_PyIO_empty_bytes = PyGC_RegisterStaticConstant(PyBytes_FromStringAndSize(NULL, 0))))
goto fail; goto fail;
if (!(_PyIO_zero = PyLong_FromLong(0L))) if (!(_PyIO_zero = PyGC_RegisterStaticConstant(PyLong_FromLong(0L))))
goto fail; goto fail;
return; return;
......
...@@ -44,6 +44,7 @@ pysqlite_microprotocols_init(PyObject *dict) ...@@ -44,6 +44,7 @@ pysqlite_microprotocols_init(PyObject *dict)
if ((psyco_adapters = PyDict_New()) == NULL) { if ((psyco_adapters = PyDict_New()) == NULL) {
return -1; return -1;
} }
PyGC_RegisterStaticConstant(psyco_adapters);
return PyDict_SetItemString(dict, "adapters", psyco_adapters); return PyDict_SetItemString(dict, "adapters", psyco_adapters);
} }
......
...@@ -230,6 +230,7 @@ static void converters_init(PyObject* dict) ...@@ -230,6 +230,7 @@ static void converters_init(PyObject* dict)
if (!converters) { if (!converters) {
return; return;
} }
PyGC_RegisterStaticConstant(converters);
PyDict_SetItemString(dict, "converters", converters); PyDict_SetItemString(dict, "converters", converters);
} }
......
...@@ -4900,10 +4900,15 @@ initdatetime(void) ...@@ -4900,10 +4900,15 @@ initdatetime(void)
assert(DI100Y == days_before_year(100+1)); assert(DI100Y == days_before_year(100+1));
us_per_us = PyInt_FromLong(1); us_per_us = PyInt_FromLong(1);
PyGC_RegisterStaticConstant(us_per_us);
us_per_ms = PyInt_FromLong(1000); us_per_ms = PyInt_FromLong(1000);
PyGC_RegisterStaticConstant(us_per_ms);
us_per_second = PyInt_FromLong(1000000); us_per_second = PyInt_FromLong(1000000);
PyGC_RegisterStaticConstant(us_per_second);
us_per_minute = PyInt_FromLong(60000000); us_per_minute = PyInt_FromLong(60000000);
PyGC_RegisterStaticConstant(us_per_minute);
seconds_per_day = PyInt_FromLong(24 * 3600); seconds_per_day = PyInt_FromLong(24 * 3600);
PyGC_RegisterStaticConstant(seconds_per_day);
if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL || if (us_per_us == NULL || us_per_ms == NULL || us_per_second == NULL ||
us_per_minute == NULL || seconds_per_day == NULL) us_per_minute == NULL || seconds_per_day == NULL)
return; return;
...@@ -4912,8 +4917,11 @@ initdatetime(void) ...@@ -4912,8 +4917,11 @@ initdatetime(void)
* us_per_week fits in 40 bits, so doubles should be exact. * us_per_week fits in 40 bits, so doubles should be exact.
*/ */
us_per_hour = PyLong_FromDouble(3600000000.0); us_per_hour = PyLong_FromDouble(3600000000.0);
PyGC_RegisterStaticConstant(us_per_hour);
us_per_day = PyLong_FromDouble(86400000000.0); us_per_day = PyLong_FromDouble(86400000000.0);
PyGC_RegisterStaticConstant(us_per_day);
us_per_week = PyLong_FromDouble(604800000000.0); us_per_week = PyLong_FromDouble(604800000000.0);
PyGC_RegisterStaticConstant(us_per_week);
if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL) if (us_per_hour == NULL || us_per_day == NULL || us_per_week == NULL)
return; return;
} }
......
...@@ -9450,8 +9450,10 @@ INITFUNC(void) ...@@ -9450,8 +9450,10 @@ INITFUNC(void)
PyModule_AddObject(m, "error", PyExc_OSError); PyModule_AddObject(m, "error", PyExc_OSError);
#ifdef HAVE_PUTENV #ifdef HAVE_PUTENV
if (posix_putenv_garbage == NULL) if (posix_putenv_garbage == NULL) {
posix_putenv_garbage = PyDict_New(); posix_putenv_garbage = PyDict_New();
PyGC_RegisterStaticConstant(posix_putenv_garbage);
}
#endif #endif
if (!initialized) { if (!initialized) {
......
...@@ -866,6 +866,7 @@ inittime(void) ...@@ -866,6 +866,7 @@ inittime(void)
/* Squirrel away the module's dictionary for the y2k check */ /* Squirrel away the module's dictionary for the y2k check */
moddict = PyModule_GetDict(m); moddict = PyModule_GetDict(m);
Py_INCREF(moddict); Py_INCREF(moddict);
PyGC_RegisterStaticConstant(moddict);
/* Set, or reset, module variables like time.timezone */ /* Set, or reset, module variables like time.timezone */
inittimezone(m); inittimezone(m);
......
...@@ -1264,6 +1264,7 @@ initzipimport(void) ...@@ -1264,6 +1264,7 @@ initzipimport(void)
zip_directory_cache = PyDict_New(); zip_directory_cache = PyDict_New();
if (zip_directory_cache == NULL) if (zip_directory_cache == NULL)
return; return;
PyGC_RegisterStaticConstant(zip_directory_cache);
Py_INCREF(zip_directory_cache); Py_INCREF(zip_directory_cache);
if (PyModule_AddObject(mod, "_zip_directory_cache", if (PyModule_AddObject(mod, "_zip_directory_cache",
zip_directory_cache) < 0) zip_directory_cache) < 0)
...@@ -1272,4 +1273,5 @@ initzipimport(void) ...@@ -1272,4 +1273,5 @@ initzipimport(void)
// Pyston change: register zip module import hook // Pyston change: register zip module import hook
PyObject* zipimporter = PyObject_GetAttrString(mod, "zipimporter"); PyObject* zipimporter = PyObject_GetAttrString(mod, "zipimporter");
PyList_Append(PySys_GetObject("path_hooks"), zipimporter); PyList_Append(PySys_GetObject("path_hooks"), zipimporter);
Py_DECREF(zipimporter);
} }
...@@ -41,9 +41,6 @@ PyStructSequence_New(PyTypeObject *type) ...@@ -41,9 +41,6 @@ PyStructSequence_New(PyTypeObject *type)
return (PyObject*) obj; return (PyObject*) obj;
} }
// Pyston change: we currently don't support finalizers, and this one is just a
// no-op (only decrefs and a final free), so we can just skip it.
#if 0
static void static void
structseq_dealloc(PyStructSequence *obj) structseq_dealloc(PyStructSequence *obj)
{ {
...@@ -55,7 +52,6 @@ structseq_dealloc(PyStructSequence *obj) ...@@ -55,7 +52,6 @@ structseq_dealloc(PyStructSequence *obj)
} }
PyObject_Del(obj); PyObject_Del(obj);
} }
#endif
static Py_ssize_t static Py_ssize_t
structseq_length(PyStructSequence *obj) structseq_length(PyStructSequence *obj)
...@@ -447,8 +443,7 @@ static PyTypeObject _struct_sequence_template = { ...@@ -447,8 +443,7 @@ static PyTypeObject _struct_sequence_template = {
NULL, /* tp_name */ NULL, /* tp_name */
0, /* tp_basicsize */ 0, /* tp_basicsize */
0, /* tp_itemsize */ 0, /* tp_itemsize */
// Pyston change: nulled this out: (destructor)structseq_dealloc, /* tp_dealloc */
0, /* tp_dealloc */
0, /* tp_print */ 0, /* tp_print */
0, /* tp_getattr */ 0, /* tp_getattr */
0, /* tp_setattr */ 0, /* tp_setattr */
...@@ -533,7 +528,11 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) ...@@ -533,7 +528,11 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
if (PyType_Ready(type) < 0) if (PyType_Ready(type) < 0)
return; return;
Py_INCREF(type);
// Pyston change: took out this INCREF.
// The type already got one base ref when it was constructed, and it looks like the
// users in the std modules don't expect this additional one.
//Py_INCREF(type);
dict = type->tp_dict; dict = type->tp_dict;
#define SET_DICT_FROM_INT(key, value) \ #define SET_DICT_FROM_INT(key, value) \
......
...@@ -534,7 +534,7 @@ extern "C" int PyObject_SetAttrString(PyObject* v, const char* name, PyObject* w ...@@ -534,7 +534,7 @@ extern "C" int PyObject_SetAttrString(PyObject* v, const char* name, PyObject* w
extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) noexcept { extern "C" PyObject* PyObject_GetAttrString(PyObject* o, const char* attr) noexcept {
try { try {
Box* r = getattrInternal<ExceptionStyle::CXX>(o, internStringMortal(attr)); Box* r = getattrInternal<ExceptionStyle::CXX>(o, autoDecref(internStringMortal(attr)));
if (!r) if (!r)
PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name, attr); PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name, attr);
return r; return r;
......
...@@ -754,7 +754,6 @@ void setupSysEnd() { ...@@ -754,7 +754,6 @@ void setupSysEnd() {
sys_module->giveAttr("builtin_module_names", sys_module->giveAttr("builtin_module_names",
BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0])); BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0]));
sys_flags_cls->finishInitialization();
/* version_info */ /* version_info */
if (VersionInfoType.tp_name == 0) if (VersionInfoType.tp_name == 0)
......
...@@ -35,6 +35,7 @@ public: ...@@ -35,6 +35,7 @@ public:
} const type; } const type;
static HiddenClass* dict_backed; static HiddenClass* dict_backed;
void dump() noexcept;
private: private:
HiddenClass(HCType type) : type(type) {} HiddenClass(HCType type) : type(type) {}
......
...@@ -573,6 +573,7 @@ static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec ar ...@@ -573,6 +573,7 @@ static Box* typeTppCall(Box* self, CallRewriteArgs* rewrite_args, ArgPassSpec ar
} }
Box* r = cpython_type_call(static_cast<BoxedClass*>(self), arg1, argspec.has_kwargs ? arg2 : NULL); Box* r = cpython_type_call(static_cast<BoxedClass*>(self), arg1, argspec.has_kwargs ? arg2 : NULL);
Py_DECREF(arg1);
if (S == CXX && !r) if (S == CXX && !r)
throwCAPIException(); throwCAPIException();
return r; return r;
...@@ -3287,11 +3288,6 @@ void dealloc_null(Box* box) { ...@@ -3287,11 +3288,6 @@ void dealloc_null(Box* box) {
assert(box->cls->tp_del == NULL); assert(box->cls->tp_del == NULL);
} }
static void setupDefaultClassGCParticipation() {
unicode_cls->is_constant = true;
unicode_cls->is_user_defined = false;
}
static Box* getsetGet(Box* self, Box* obj, Box* type) { static Box* getsetGet(Box* self, Box* obj, Box* type) {
// TODO: should call the full descr_check instead // TODO: should call the full descr_check instead
if (obj == NULL || obj == None) if (obj == NULL || obj == None)
...@@ -3353,6 +3349,20 @@ void Box::clearAttrs() { ...@@ -3353,6 +3349,20 @@ void Box::clearAttrs() {
} }
} }
void HiddenClass::dump() noexcept {
if (type == SINGLETON || type == NORMAL) {
if (type == SINGLETON)
printf("Singleton hcls:\n");
else
printf("Normal hcls:\n");
printf("Attrwrapper offset: %d\n", attrwrapper_offset);
for (auto p : attr_offsets) {
//printf("%d: %s\n", p.second, p.first->c_str());
printf("%d: %p\n", p.second, p.first);
}
}
}
void HCAttrs::clear() noexcept { void HCAttrs::clear() noexcept {
HiddenClass* hcls = this->hcls; HiddenClass* hcls = this->hcls;
...@@ -4008,6 +4018,8 @@ void setupRuntime() { ...@@ -4008,6 +4018,8 @@ void setupRuntime() {
setupClassobj(); setupClassobj();
setupSuper(); setupSuper();
_PyUnicode_Init(); _PyUnicode_Init();
unicode_cls->is_constant = true;
unicode_cls->is_user_defined = false;
setupDescr(); setupDescr();
setupTraceback(); setupTraceback();
setupCode(); setupCode();
......
...@@ -19,6 +19,7 @@ ...@@ -19,6 +19,7 @@
#include "core/options.h" #include "core/options.h"
#include "core/types.h" #include "core/types.h"
#include "runtime/long.h" #include "runtime/long.h"
#include "runtime/hiddenclass.h"
#include "runtime/objmodel.h" #include "runtime/objmodel.h"
namespace pyston { namespace pyston {
...@@ -154,6 +155,13 @@ extern "C" void dumpEx(void* p, int levels) { ...@@ -154,6 +155,13 @@ extern "C" void dumpEx(void* p, int levels) {
printf("Guessing that it's a Python object\n"); printf("Guessing that it's a Python object\n");
Box* b = (Box*)p; Box* b = (Box*)p;
if (b->cls->instancesHaveHCAttrs()) {
printf("Object has hcattrs:\n");
HCAttrs* attrs = b->getHCAttrsPtr();
attrs->hcls->dump();
//attrs->dump();
}
printf("Class: %s", b->cls->tp_name); printf("Class: %s", b->cls->tp_name);
if (b->cls->cls != type_cls) { if (b->cls->cls != type_cls) {
printf(" (metaclass: %s)\n", getFullTypeName(b->cls).c_str()); printf(" (metaclass: %s)\n", getFullTypeName(b->cls).c_str());
......
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