Commit cb5df340 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Clean up shutdown code

joinRuntime+teardownRuntime->Py_Finalize
remove the individual teardownFoo(), which had all become empty anyway.
parent 37927451
......@@ -382,12 +382,12 @@ static void handle_sigint(int signum) {
// TODO: this should set a flag saying a KeyboardInterrupt is pending.
// For now, just call abort(), so that we get a traceback at least.
fprintf(stderr, "SIGINT!\n");
joinRuntime();
Py_Finalize();
Stats::dump(false);
abort();
}
void initCodegen() {
extern "C" void Py_Initialize() noexcept {
llvm::InitializeNativeTarget();
llvm::InitializeNativeTargetAsmPrinter();
llvm::InitializeNativeTargetAsmParser();
......@@ -529,6 +529,9 @@ void initCodegen() {
}
void teardownCodegen() {
if (PROFILE)
g.func_addr_registry.dumpPerfMap();
for (int i = 0; i < g.jit_listeners.size(); i++) {
g.engine->UnregisterJITEventListener(g.jit_listeners[i]);
delete g.jit_listeners[i];
......@@ -541,17 +544,4 @@ void printAllIR() {
assert(0 && "unimplemented");
fprintf(stderr, "==============\n");
}
int joinRuntime() {
// In the future this will have to wait for non-daemon
// threads to finish
if (PROFILE)
g.func_addr_registry.dumpPerfMap();
teardownRuntime();
teardownCodegen();
return 0;
}
}
......@@ -20,10 +20,8 @@ namespace pyston {
class AST_Module;
class BoxedModule;
void initCodegen();
void teardownCodegen();
void printAllIR();
int joinRuntime();
}
#endif
......@@ -815,7 +815,6 @@ class BoxedClass;
// TODO these shouldn't be here
void setupRuntime();
void teardownRuntime();
Box* createAndRunModule(BoxedString* name, const std::string& fn);
BoxedModule* createModule(BoxedString* name, const char* fn = NULL, const char* doc = NULL);
Box* moduleInit(BoxedModule* self, Box* name, Box* doc = NULL);
......
......@@ -296,7 +296,7 @@ static int RunMainFromImporter(const char* filename) {
return -1;
}
static int main(int argc, char** argv) {
static int main(int argc, char** argv) noexcept {
argv0 = argv[0];
Timer _t("for jit startup");
......@@ -384,8 +384,8 @@ static int main(int argc, char** argv) {
}
{
Timer _t("for initCodegen");
initCodegen();
Timer _t("for Py_Initialize");
Py_Initialize();
}
// Arguments left over after option parsing are of the form:
......@@ -526,9 +526,9 @@ static int main(int argc, char** argv) {
// Note: we will purposefully not release the GIL on exiting.
threading::promoteGL();
_t.split("joinRuntime");
_t.split("Py_Finalize");
joinRuntime();
Py_Finalize();
_t.split("finishing up");
#if STAT_TIMERS
......
......@@ -104,7 +104,4 @@ void setupBool() {
bool_cls->freeze();
bool_cls->tp_hash = (hashfunc)bool_hash;
}
void teardownBool() {
}
}
......@@ -2008,7 +2008,4 @@ void setupCAPI() {
capifunc_cls->freeze();
}
void teardownCAPI() {
}
}
......@@ -1295,7 +1295,4 @@ void setupComplex() {
complex_cls->tp_as_number->nb_negative = (unaryfunc)complex_neg;
complex_cls->tp_richcompare = complex_richcompare;
}
void teardownComplex() {
}
}
......@@ -783,7 +783,4 @@ void setupDescr() {
new BoxedFunction(FunctionMetadata::create((void*)wrapperObjectRepr, UNKNOWN, 1)));
wrapperobject_cls->freeze();
}
void teardownDescr() {
}
}
......@@ -909,7 +909,4 @@ void setupDict() {
(void*)dictViewItemsIter, typeFromClass(dict_iterator_cls), 1)));
dict_items_cls->freeze();
}
void teardownDict() {
}
}
......@@ -1897,7 +1897,4 @@ void setupFile() {
file_cls->freeze();
}
void teardownFile() {
}
}
......@@ -1709,7 +1709,4 @@ void setupFloat() {
float_cls->tp_str = float_str;
float_cls->tp_as_number->nb_power = float_pow;
}
void teardownFloat() {
}
}
......@@ -1225,7 +1225,4 @@ void setupInt() {
int_cls->tp_repr = (reprfunc)int_to_decimal_string;
}
void teardownInt() {
}
}
......@@ -1397,10 +1397,4 @@ void setupList() {
list_reverse_iterator_cls->tp_iternext = listreviter_next;
list_reverse_iterator_cls->tp_iter = PyObject_SelfIter;
}
void teardownList() {
// TODO do clearattrs?
// decref(list_iterator_cls);
// decref(list_reverse_iterator_cls);
}
}
......@@ -957,6 +957,21 @@ struct method_cache_entry {
static struct method_cache_entry method_cache[1 << MCACHE_SIZE_EXP];
static unsigned int next_version_tag = 0;
extern "C" unsigned int PyType_ClearCache() noexcept {
Py_ssize_t i;
unsigned int cur_version_tag = next_version_tag - 1;
for (i = 0; i < (1 << MCACHE_SIZE_EXP); i++) {
method_cache[i].version = 0;
Py_CLEAR(method_cache[i].name);
method_cache[i].value = NULL;
}
next_version_tag = 0;
/* mark all version tags as invalid */
PyType_Modified(&PyBaseObject_Type);
return cur_version_tag;
}
int assign_version_tag(PyTypeObject* type) noexcept {
/* Ensure that the tp_version_tag is valid and set
Py_TPFLAGS_VALID_VERSION_TAG. To respect the invariant, this
......
......@@ -975,7 +975,4 @@ void setupSet() {
set_cls->tp_iter = (decltype(set_cls->tp_iter))setIter;
frozenset_cls->tp_iter = (decltype(frozenset_cls->tp_iter))setIter;
}
void teardownSet() {
}
}
......@@ -22,7 +22,6 @@
namespace pyston {
void setupSet();
void teardownSet();
extern "C" Box* createSet();
......
......@@ -2915,7 +2915,4 @@ void setupStr() {
new BoxedFunction(FunctionMetadata::create((void*)basestringNew, UNKNOWN, 1, true, true)));
basestring_cls->freeze();
}
void teardownStr() {
}
}
......@@ -718,9 +718,4 @@ void setupTuple() {
tuple_iterator_cls->tp_iternext = tupleiter_next;
tuple_iterator_cls->tp_iter = PyObject_SelfIter;
}
void teardownTuple() {
// TODO do clearattrs?
// decref(tuple_iterator_cls);
}
}
......@@ -28,6 +28,7 @@
#include "capi/typeobject.h"
#include "capi/types.h"
#include "codegen/ast_interpreter.h"
#include "codegen/entry.h"
#include "codegen/unwinding.h"
#include "core/ast.h"
#include "core/options.h"
......@@ -92,8 +93,6 @@ namespace pyston {
void setupGC();
bool IN_SHUTDOWN = false;
std::vector<BoxedClass*> exception_types;
void FrameInfo::gcVisit(GCVisitor* visitor) {
......@@ -4166,65 +4165,142 @@ BoxedModule* createModule(BoxedString* name, const char* fn, const char* doc) {
return module;
}
void teardownRuntime() {
// Things start to become very precarious after this point, as the basic classes stop to work.
// TODO it's probably a waste of time to tear these down in non-debugging mode
IN_SHUTDOWN = true;
if (VERBOSITY("runtime") >= 1)
printf("In teardownRuntime\n");
teardownCAPI();
teardownList();
teardownInt();
teardownFloat();
teardownComplex();
teardownStr();
teardownBool();
teardownDict();
teardownSet();
teardownTuple();
teardownFile();
teardownDescr();
/*
// clear all the attributes on the base classes before freeing the classes themselves,
// since we will run into problem if we free a class but there is an object somewhere
// else that refers to it.
clearAttrs(bool_cls);
clearAttrs(int_cls);
clearAttrs(float_cls);
clearAttrs(none_cls);
clearAttrs(function_cls);
clearAttrs(instancemethod_cls);
clearAttrs(str_cls);
clearAttrs(list_cls);
clearAttrs(slice_cls);
clearAttrs(type_cls);
clearAttrs(module_cls);
clearAttrs(dict_cls);
clearAttrs(tuple_cls);
clearAttrs(file_cls);
decref(bool_cls);
decref(int_cls);
decref(float_cls);
decref(function_cls);
decref(instancemethod_cls);
decref(str_cls);
decref(list_cls);
decref(slice_cls);
decref(module_cls);
decref(dict_cls);
decref(tuple_cls);
decref(file_cls);
ASSERT(None->nrefs == 1, "%ld", None->nrefs);
decref(None);
decref(none_cls);
decref(type_cls);
*/
static void call_sys_exitfunc(void) {
PyObject* exitfunc = PySys_GetObject("exitfunc");
if (exitfunc) {
PyObject* res;
Py_INCREF(exitfunc);
PySys_SetObject("exitfunc", (PyObject*)NULL);
res = PyEval_CallObject(exitfunc, (PyObject*)NULL);
if (res == NULL) {
if (!PyErr_ExceptionMatches(PyExc_SystemExit)) {
PySys_WriteStderr("Error in sys.exitfunc:\n");
}
PyErr_Print();
}
Py_DECREF(exitfunc);
}
if (Py_FlushLine())
PyErr_Clear();
}
#ifndef Py_REF_DEBUG
#define PRINT_TOTAL_REFS()
#else /* Py_REF_DEBUG */
#define PRINT_TOTAL_REFS() fprintf(stderr, "[%" PY_FORMAT_SIZE_T "d refs]\n", _Py_GetRefTotal())
#endif
extern "C" void Py_Finalize() noexcept {
// In the future this will have to wait for non-daemon
// threads to finish
// wait_for_thread_shutdown();
call_sys_exitfunc();
// initialized = 0;
// PyOS_FiniInterrupts();
PyType_ClearCache();
// PyGC_Collect());
// PyImport_Cleanup();
// _PyImport_Fini();
// _PyExc_Fini();
// _PyGILState_Fini();
// TODO it's probably a waste of time to tear these down in non-debugging mode
/*
// clear all the attributes on the base classes before freeing the classes themselves,
// since we will run into problem if we free a class but there is an object somewhere
// else that refers to it.
clearAttrs(bool_cls);
clearAttrs(int_cls);
clearAttrs(float_cls);
clearAttrs(none_cls);
clearAttrs(function_cls);
clearAttrs(instancemethod_cls);
clearAttrs(str_cls);
clearAttrs(list_cls);
clearAttrs(slice_cls);
clearAttrs(type_cls);
clearAttrs(module_cls);
clearAttrs(dict_cls);
clearAttrs(tuple_cls);
clearAttrs(file_cls);
decref(bool_cls);
decref(int_cls);
decref(float_cls);
decref(function_cls);
decref(instancemethod_cls);
decref(str_cls);
decref(list_cls);
decref(slice_cls);
decref(module_cls);
decref(dict_cls);
decref(tuple_cls);
decref(file_cls);
ASSERT(None->nrefs == 1, "%ld", None->nrefs);
decref(None);
decref(none_cls);
decref(type_cls);
*/
#if 0
/* Delete current thread */
PyThreadState_Swap(NULL);
PyInterpreterState_Delete(interp);
/* Sundry finalizers */
PyMethod_Fini();
PyFrame_Fini();
PyCFunction_Fini();
PyTuple_Fini();
PyList_Fini();
PySet_Fini();
PyString_Fini();
PyByteArray_Fini();
PyInt_Fini();
PyFloat_Fini();
PyDict_Fini();
#ifdef Py_USING_UNICODE
/* Cleanup Unicode implementation */
_PyUnicode_Fini();
#endif
/* XXX Still allocated:
* - various static ad-hoc pointers to interned strings
* - int and float free list blocks
* - whatever various modules and libraries allocate
* */
PyGrammar_RemoveAccelerators(&_PyParser_Grammar);
#ifdef Py_TRACE_REFS
/* Display addresses (& refcnts) of all objects still alive.
* * An address can be used to find the repr of the object, printed
* * above by _Py_PrintReferences.
* */
if (Py_GETENV("PYTHONDUMPREFS"))
_Py_PrintReferenceAddresses(stderr);
#endif /* Py_TRACE_REFS */
#ifdef PYMALLOC_DEBUG
if (Py_GETENV("PYTHONMALLOCSTATS"))
_PyObject_DebugMallocStats();
#endif
#endif
teardownCodegen();
PRINT_TOTAL_REFS();
}
}
......@@ -43,32 +43,21 @@ class BoxedGenerator;
class BoxedLong;
void setupInt();
void teardownInt();
void setupFloat();
void teardownFloat();
void setupComplex();
void teardownComplex();
void setupStr();
void teardownStr();
void setupList();
void teardownList();
void list_dtor(BoxedList* l);
void setupBool();
void teardownBool();
void dict_dtor(BoxedDict* d);
void setupDict();
void teardownDict();
void tuple_dtor(BoxedTuple* d);
void setupTuple();
void teardownTuple();
void file_dtor(BoxedFile* d);
void setupFile();
void teardownFile();
void setupCAPI();
void teardownCAPI();
void setupGenerator();
void setupDescr();
void teardownDescr();
void setupCode();
void setupFrame();
......
......@@ -20,7 +20,7 @@ using namespace pyston;
class AnalysisTest : public ::testing::Test {
protected:
static void SetUpTestCase() {
initCodegen();
Py_Initialize();
}
};
......
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