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)
PyAPI_FUNC(void) PyType_SetDict(PyTypeObject*, PyObject*) PYSTON_NOEXCEPT;
// 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.
PyAPI_FUNC(void) PyGC_RegisterStaticConstant(PyObject*) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject*) PyGC_RegisterStaticConstant(PyObject*) PYSTON_NOEXCEPT;
// Pyston addition:
PyAPI_FUNC(void) PyGC_Enable() PYSTON_NOEXCEPT;
......
......@@ -1625,5 +1625,10 @@ init_csv(void)
error_obj = PyErr_NewException("_csv.Error", NULL, NULL);
if (error_obj == NULL)
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);
}
......@@ -712,63 +712,61 @@ init_io(void)
/* IncrementalNewlineDecoder */
ADD_TYPE(&PyIncrementalNewlineDecoder_Type, "IncrementalNewlineDecoder");
// Pyston change: register with gc
// TODO: automatically register static variables as roots
/* Interned strings */
// 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.
if (!(_PyIO_str_close = PyString_FromString("close")))
if (!(_PyIO_str_close = PyGC_RegisterStaticConstant(PyString_InternFromString("close"))))
goto fail;
if (!(_PyIO_str_closed = PyString_FromString("closed")))
if (!(_PyIO_str_closed = PyGC_RegisterStaticConstant(PyString_InternFromString("closed"))))
goto fail;
if (!(_PyIO_str_decode = PyString_FromString("decode")))
if (!(_PyIO_str_decode = PyGC_RegisterStaticConstant(PyString_InternFromString("decode"))))
goto fail;
if (!(_PyIO_str_encode = PyString_FromString("encode")))
if (!(_PyIO_str_encode = PyGC_RegisterStaticConstant(PyString_InternFromString("encode"))))
goto fail;
if (!(_PyIO_str_fileno = PyString_FromString("fileno")))
if (!(_PyIO_str_fileno = PyGC_RegisterStaticConstant(PyString_InternFromString("fileno"))))
goto fail;
if (!(_PyIO_str_flush = PyString_FromString("flush")))
if (!(_PyIO_str_flush = PyGC_RegisterStaticConstant(PyString_InternFromString("flush"))))
goto fail;
if (!(_PyIO_str_getstate = PyString_FromString("getstate")))
if (!(_PyIO_str_getstate = PyGC_RegisterStaticConstant(PyString_InternFromString("getstate"))))
goto fail;
if (!(_PyIO_str_isatty = PyString_FromString("isatty")))
if (!(_PyIO_str_isatty = PyGC_RegisterStaticConstant(PyString_InternFromString("isatty"))))
goto fail;
if (!(_PyIO_str_newlines = PyString_FromString("newlines")))
if (!(_PyIO_str_newlines = PyGC_RegisterStaticConstant(PyString_InternFromString("newlines"))))
goto fail;
if (!(_PyIO_str_nl = PyString_FromString("\n")))
if (!(_PyIO_str_nl = PyGC_RegisterStaticConstant(PyString_InternFromString("\n"))))
goto fail;
if (!(_PyIO_str_read = PyString_FromString("read")))
if (!(_PyIO_str_read = PyGC_RegisterStaticConstant(PyString_InternFromString("read"))))
goto fail;
if (!(_PyIO_str_read1 = PyString_FromString("read1")))
if (!(_PyIO_str_read1 = PyGC_RegisterStaticConstant(PyString_InternFromString("read1"))))
goto fail;
if (!(_PyIO_str_readable = PyString_FromString("readable")))
if (!(_PyIO_str_readable = PyGC_RegisterStaticConstant(PyString_InternFromString("readable"))))
goto fail;
if (!(_PyIO_str_readinto = PyString_FromString("readinto")))
if (!(_PyIO_str_readinto = PyGC_RegisterStaticConstant(PyString_InternFromString("readinto"))))
goto fail;
if (!(_PyIO_str_readline = PyString_FromString("readline")))
if (!(_PyIO_str_readline = PyGC_RegisterStaticConstant(PyString_InternFromString("readline"))))
goto fail;
if (!(_PyIO_str_reset = PyString_FromString("reset")))
if (!(_PyIO_str_reset = PyGC_RegisterStaticConstant(PyString_InternFromString("reset"))))
goto fail;
if (!(_PyIO_str_seek = PyString_FromString("seek")))
if (!(_PyIO_str_seek = PyGC_RegisterStaticConstant(PyString_InternFromString("seek"))))
goto fail;
if (!(_PyIO_str_seekable = PyString_FromString("seekable")))
if (!(_PyIO_str_seekable = PyGC_RegisterStaticConstant(PyString_InternFromString("seekable"))))
goto fail;
if (!(_PyIO_str_setstate = PyString_FromString("setstate")))
if (!(_PyIO_str_setstate = PyGC_RegisterStaticConstant(PyString_InternFromString("setstate"))))
goto fail;
if (!(_PyIO_str_tell = PyString_FromString("tell")))
if (!(_PyIO_str_tell = PyGC_RegisterStaticConstant(PyString_InternFromString("tell"))))
goto fail;
if (!(_PyIO_str_truncate = PyString_FromString("truncate")))
if (!(_PyIO_str_truncate = PyGC_RegisterStaticConstant(PyString_InternFromString("truncate"))))
goto fail;
if (!(_PyIO_str_write = PyString_FromString("write")))
if (!(_PyIO_str_write = PyGC_RegisterStaticConstant(PyString_InternFromString("write"))))
goto fail;
if (!(_PyIO_str_writable = PyString_FromString("writable")))
if (!(_PyIO_str_writable = PyGC_RegisterStaticConstant(PyString_InternFromString("writable"))))
goto fail;
if (!(_PyIO_empty_str = PyUnicode_FromStringAndSize(NULL, 0)))
if (!(_PyIO_empty_str = PyGC_RegisterStaticConstant(PyUnicode_FromStringAndSize(NULL, 0))))
goto fail;
if (!(_PyIO_empty_bytes = PyBytes_FromStringAndSize(NULL, 0)))
if (!(_PyIO_empty_bytes = PyGC_RegisterStaticConstant(PyBytes_FromStringAndSize(NULL, 0))))
goto fail;
if (!(_PyIO_zero = PyLong_FromLong(0L)))
if (!(_PyIO_zero = PyGC_RegisterStaticConstant(PyLong_FromLong(0L))))
goto fail;
return;
......
......@@ -44,6 +44,7 @@ pysqlite_microprotocols_init(PyObject *dict)
if ((psyco_adapters = PyDict_New()) == NULL) {
return -1;
}
PyGC_RegisterStaticConstant(psyco_adapters);
return PyDict_SetItemString(dict, "adapters", psyco_adapters);
}
......
......@@ -230,6 +230,7 @@ static void converters_init(PyObject* dict)
if (!converters) {
return;
}
PyGC_RegisterStaticConstant(converters);
PyDict_SetItemString(dict, "converters", converters);
}
......
......@@ -4900,10 +4900,15 @@ initdatetime(void)
assert(DI100Y == days_before_year(100+1));
us_per_us = PyInt_FromLong(1);
PyGC_RegisterStaticConstant(us_per_us);
us_per_ms = PyInt_FromLong(1000);
PyGC_RegisterStaticConstant(us_per_ms);
us_per_second = PyInt_FromLong(1000000);
PyGC_RegisterStaticConstant(us_per_second);
us_per_minute = PyInt_FromLong(60000000);
PyGC_RegisterStaticConstant(us_per_minute);
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 ||
us_per_minute == NULL || seconds_per_day == NULL)
return;
......@@ -4912,8 +4917,11 @@ initdatetime(void)
* us_per_week fits in 40 bits, so doubles should be exact.
*/
us_per_hour = PyLong_FromDouble(3600000000.0);
PyGC_RegisterStaticConstant(us_per_hour);
us_per_day = PyLong_FromDouble(86400000000.0);
PyGC_RegisterStaticConstant(us_per_day);
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)
return;
}
......
......@@ -9450,8 +9450,10 @@ INITFUNC(void)
PyModule_AddObject(m, "error", PyExc_OSError);
#ifdef HAVE_PUTENV
if (posix_putenv_garbage == NULL)
if (posix_putenv_garbage == NULL) {
posix_putenv_garbage = PyDict_New();
PyGC_RegisterStaticConstant(posix_putenv_garbage);
}
#endif
if (!initialized) {
......
......@@ -866,6 +866,7 @@ inittime(void)
/* Squirrel away the module's dictionary for the y2k check */
moddict = PyModule_GetDict(m);
Py_INCREF(moddict);
PyGC_RegisterStaticConstant(moddict);
/* Set, or reset, module variables like time.timezone */
inittimezone(m);
......
......@@ -1264,6 +1264,7 @@ initzipimport(void)
zip_directory_cache = PyDict_New();
if (zip_directory_cache == NULL)
return;
PyGC_RegisterStaticConstant(zip_directory_cache);
Py_INCREF(zip_directory_cache);
if (PyModule_AddObject(mod, "_zip_directory_cache",
zip_directory_cache) < 0)
......@@ -1272,4 +1273,5 @@ initzipimport(void)
// Pyston change: register zip module import hook
PyObject* zipimporter = PyObject_GetAttrString(mod, "zipimporter");
PyList_Append(PySys_GetObject("path_hooks"), zipimporter);
Py_DECREF(zipimporter);
}
......@@ -41,9 +41,6 @@ PyStructSequence_New(PyTypeObject *type)
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
structseq_dealloc(PyStructSequence *obj)
{
......@@ -55,7 +52,6 @@ structseq_dealloc(PyStructSequence *obj)
}
PyObject_Del(obj);
}
#endif
static Py_ssize_t
structseq_length(PyStructSequence *obj)
......@@ -447,8 +443,7 @@ static PyTypeObject _struct_sequence_template = {
NULL, /* tp_name */
0, /* tp_basicsize */
0, /* tp_itemsize */
// Pyston change: nulled this out:
0, /* tp_dealloc */
(destructor)structseq_dealloc, /* tp_dealloc */
0, /* tp_print */
0, /* tp_getattr */
0, /* tp_setattr */
......@@ -533,7 +528,11 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
if (PyType_Ready(type) < 0)
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;
#define SET_DICT_FROM_INT(key, value) \
......
......@@ -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 {
try {
Box* r = getattrInternal<ExceptionStyle::CXX>(o, internStringMortal(attr));
Box* r = getattrInternal<ExceptionStyle::CXX>(o, autoDecref(internStringMortal(attr)));
if (!r)
PyErr_Format(PyExc_AttributeError, "'%.50s' object has no attribute '%.400s'", o->cls->tp_name, attr);
return r;
......
......@@ -754,7 +754,6 @@ void setupSysEnd() {
sys_module->giveAttr("builtin_module_names",
BoxedTuple::create(builtin_module_names.size(), &builtin_module_names[0]));
sys_flags_cls->finishInitialization();
/* version_info */
if (VersionInfoType.tp_name == 0)
......
......@@ -35,6 +35,7 @@ public:
} const type;
static HiddenClass* dict_backed;
void dump() noexcept;
private:
HiddenClass(HCType type) : type(type) {}
......
......@@ -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);
Py_DECREF(arg1);
if (S == CXX && !r)
throwCAPIException();
return r;
......@@ -3287,11 +3288,6 @@ void dealloc_null(Box* box) {
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) {
// TODO: should call the full descr_check instead
if (obj == NULL || obj == None)
......@@ -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 {
HiddenClass* hcls = this->hcls;
......@@ -4008,6 +4018,8 @@ void setupRuntime() {
setupClassobj();
setupSuper();
_PyUnicode_Init();
unicode_cls->is_constant = true;
unicode_cls->is_user_defined = false;
setupDescr();
setupTraceback();
setupCode();
......
......@@ -19,6 +19,7 @@
#include "core/options.h"
#include "core/types.h"
#include "runtime/long.h"
#include "runtime/hiddenclass.h"
#include "runtime/objmodel.h"
namespace pyston {
......@@ -154,6 +155,13 @@ extern "C" void dumpEx(void* p, int levels) {
printf("Guessing that it's a Python object\n");
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);
if (b->cls->cls != type_cls) {
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