Commit 4027c960 authored by Marius Wachtler's avatar Marius Wachtler

Merge pull request #1157 from undingen/ref_integration

refcounting changes for our integration tests
parents 578297b9 194bcb9e
......@@ -49,6 +49,11 @@ option(ENABLE_LLVM_DEBUG "LLVM debug symbols" OFF)
option(ENABLE_OPROFILE "enable oprofile support" OFF)
option(ENABLE_SELF_HOST "use pyston to test pyston" OFF)
option(ENABLE_VALGRIND "pyston valgrind support" OFF)
if(${CMAKE_BUILD_TYPE} STREQUAL "Debug")
option(ENABLE_REF_DEBUG "enable memory and refcounting debugging" ON)
else()
option(ENABLE_REF_DEBUG "enable memory and refcounting debugging" OFF)
endif()
option(ENABLE_PGO "enable -fprofile-generate/-fprofile-use" OFF)
option(ENABLE_LTO "enable -flto" OFF)
......@@ -105,6 +110,12 @@ if(ENABLE_PGO)
set(PGO_FLAGS "-fprofile-${PROFILE_STATE} -fprofile-correction")
endif()
if(ENABLE_REF_DEBUG)
add_definitions(-DPy_REF_DEBUG)
add_definitions(-DPYMALLOC_DEBUG)
add_definitions(-DPy_TRACE_REFS)
endif()
macro(ADD_PROFILE_FLAGS)
set(PROFILE_FLAGS "${PGO_FLAGS} ${LTO_FLAGS}")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROFILE_FLAGS}")
......
......@@ -4,4 +4,8 @@ else()
set(EXT_BUILD_FLAGS "-g -O0")
endif()
if (${ENABLE_REF_DEBUG})
set(EXT_BUILD_FLAGS "-DPy_REF_DEBUG -DPYMALLOC_DEBUG -DPy_TRACE_REFS ${EXT_BUILD_FLAGS}")
endif()
configure_file(lib_pyston/_sysconfigdata.py.in lib_pyston/_sysconfigdata.py)
......@@ -21,12 +21,6 @@
#define PYSTON_VERSION "0.5"
#define WITH_PYMALLOC
// XXX: testing
#ifndef NDEBUG
#define Py_REF_DEBUG
#define PYMALLOC_DEBUG
#define Py_TRACE_REFS
#endif
// These include orders come from CPython:
#include "patchlevel.h"
......
......@@ -246,7 +246,6 @@ BaseException_repr(PyBaseExceptionObject *self)
static PyObject *
BaseException_reduce(PyBaseExceptionObject *self)
{
assert(0 && "check refcounting");
/* Pyston change:
if (self->args && self->dict)
return PyTuple_Pack(3, Py_TYPE(self), self->args, self->dict);
......@@ -853,7 +852,6 @@ EnvironmentError_reduce(PyEnvironmentErrorObject *self)
} else
Py_INCREF(args);
assert(0 && "check refcounting");
/* Pyston change:
if (self->dict)
res = PyTuple_Pack(3, Py_TYPE(self), args, self->dict);
......@@ -864,7 +862,9 @@ EnvironmentError_reduce(PyEnvironmentErrorObject *self)
PyObject* attr_wrapper = PyObject_GetAttrWrapper((PyObject*)self);
if (!attr_wrapper)
return NULL;
return PyTuple_Pack(3, Py_TYPE(self), args, attr_wrapper);
res = PyTuple_Pack(3, Py_TYPE(self), args, attr_wrapper);
Py_DECREF(args);
return res;
}
......
......@@ -2520,16 +2520,4 @@ PatchpointInitializationInfo initializePatchpoint3(void* slowpath_func, uint8_t*
return PatchpointInitializationInfo(slowpath_start, slowpath_rtn_addr, continue_addr, std::move(live_outs));
}
void* Rewriter::RegionAllocator::alloc(size_t bytes) {
assert(bytes <= BLOCK_SIZE);
if (cur_offset + bytes > BLOCK_SIZE) {
blocks.emplace_back();
cur_offset = 0;
}
char* rtn = blocks.back() + cur_offset;
cur_offset += bytes;
return rtn;
}
}
......@@ -330,30 +330,9 @@ enum class ActionType { NORMAL, GUARD, MUTATION };
#define LOCATION_PLACEHOLDER ((RewriterVar*)1)
class Rewriter : public ICSlotRewrite::CommitHook {
private:
class RegionAllocator {
public:
static const int BLOCK_SIZE = 1024; // reserve a bit of space for list/malloc overhead
std::list<char[BLOCK_SIZE]> blocks;
int cur_offset = BLOCK_SIZE + 1;
void* alloc(size_t bytes);
};
template <typename T> class RegionAllocatorAdaptor : public std::allocator<T> {
private:
RegionAllocator* allocator;
public:
T* allocate(size_t n) { return (T*)allocator->alloc(n); }
void deallocate(T* p, size_t n) {
// do nothing
}
};
private:
// This needs to be the first member:
RegionAllocator allocator;
llvm::BumpPtrAllocatorImpl<llvm::MallocAllocator, 512> allocator;
// The rewriter has refcounting logic for handling owned RewriterVars. If we own memory inside those RewriterVars,
// we need to register that via registerOwnedAttr, which ends up here:
......@@ -361,7 +340,7 @@ private:
protected:
// Allocates `bytes` bytes of data. The allocation will get freed when the rewriter gets freed.
void* regionAlloc(size_t bytes) { return allocator.alloc(bytes); }
void* regionAlloc(size_t bytes) { return allocator.Allocate(bytes, 16 /* alignment */); }
// Helps generating the best code for loading a const integer value.
// By keeping track of the last known value of every register and reusing it.
......@@ -425,7 +404,7 @@ protected:
Rewriter(std::unique_ptr<ICSlotRewrite> rewrite, int num_args, const LiveOutSet& live_outs,
bool needs_invalidation_support = true);
std::deque<RewriterAction, RegionAllocatorAdaptor<RewriterAction>> actions;
std::deque<RewriterAction> actions;
template <typename F> RewriterAction* addAction(F&& action, llvm::ArrayRef<RewriterVar*> vars, ActionType type) {
assertPhaseCollecting();
for (RewriterVar* var : vars) {
......
......@@ -696,7 +696,9 @@ extern "C" PyObject* PyObject_CallMethodObjArgs(PyObject* callable, PyObject* na
}
}
Py_INCREF(attr);
internStringMortalInplace(attr);
AUTO_DECREF(attr);
tmp = callattrInternal<ExceptionStyle::CAPI, NOT_REWRITABLE>(
callable, attr, CLASS_OR_INST, NULL, ArgPassSpec(0, 0, true, false), args, NULL, NULL, NULL, NULL);
if (!tmp && !PyErr_Occurred())
......
......@@ -3504,7 +3504,6 @@ extern "C" int PyType_Ready(PyTypeObject* cls) noexcept {
RELEASE_ASSERT(cls->tp_cache == NULL, "");
RELEASE_ASSERT(cls->tp_subclasses == NULL, "");
RELEASE_ASSERT(cls->tp_weaklist == NULL, "");
RELEASE_ASSERT(cls->tp_del == NULL, "");
RELEASE_ASSERT(cls->tp_version_tag == 0, "");
// I think it is safe to ignore these for for now:
......
......@@ -1872,7 +1872,8 @@ Box* BoxedCApiFunction::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPa
rewrite_args->out_success = true;
}
checkAndThrowCAPIException();
if (!rtn)
throwCAPIException();
assert(rtn && "should have set + thrown an exception!");
return rtn;
}
......
......@@ -202,7 +202,8 @@ extern "C" void raise3(STOLEN(Box*) arg0, STOLEN(Box*) arg1, STOLEN(Box*) arg2)
if (reraise)
startReraise();
assert(!PyErr_Occurred());
if (PyErr_Occurred())
PyErr_Clear();
throw exc_info;
}
......
......@@ -32,6 +32,10 @@
namespace pyston {
#ifdef Py_REF_DEBUG
bool imported_foreign_cextension = false;
#endif
static void removeModule(BoxedString* name) {
BoxedDict* d = getSysModulesDict();
PyDict_DelItem(d, name);
......@@ -174,6 +178,12 @@ BoxedModule* importCExtension(BoxedString* full_name, const std::string& last_na
if (Py_VerboseFlag)
PySys_WriteStderr("import %s # dynamically loaded from %s\n", full_name->c_str(), path.c_str());
#ifdef Py_REF_DEBUG
// if we load a foreign C extension we can't check that _Py_RefTotal == 0
if (!llvm::StringRef(path).endswith("from_cpython/Lib/" + last_name + ".pyston.so"))
imported_foreign_cextension = true;
#endif
return incref(m);
}
}
......@@ -22,6 +22,10 @@ namespace pyston {
extern "C" PyObject* PyImport_GetImporter(PyObject* path) noexcept;
extern "C" Box* import(int level, Box* from_imports, llvm::StringRef module_name);
BoxedModule* importCExtension(BoxedString* full_name, const std::string& last_name, const std::string& path);
#ifdef Py_REF_DEBUG
extern bool imported_foreign_cextension;
#endif
}
#endif
......@@ -138,6 +138,7 @@ void BoxedList::shrink() {
capacity = new_capacity;
} else if (size == 0) {
delete elts;
elts = NULL;
capacity = 0;
}
}
......
......@@ -560,14 +560,14 @@ static inline void listSetitemSliceInt64(BoxedList* self, i64 start, i64 stop, i
memmove(self->elts->elts + start + v_size, self->elts->elts + stop, remaining_elts * sizeof(Box*));
for (int i = 0; i < v_size; i++) {
Box* r = v_elts[i];
Py_INCREF(r);
Py_XINCREF(r);
self->elts->elts[start + i] = r;
}
self->size += delts;
for (int i = 0; i < stop - start; i++) {
Py_DECREF(removed_elts[i]);
Py_XDECREF(removed_elts[i]);
}
if (removed_elts)
PyMem_FREE(removed_elts);
......
......@@ -1357,14 +1357,33 @@ void HCAttrs::moduleClear() noexcept {
if (!hcls)
return;
RELEASE_ASSERT(hcls->type == HiddenClass::NORMAL || hcls->type == HiddenClass::SINGLETON, "");
auto&& first_check_func = [](const char* s) { return s[0] == '_' && s[1] != '_'; };
auto&& second_check_func = [](const char* s) { return s[0] != '_' || strcmp(s, "__builtins__") != 0; };
if (hcls->type == HiddenClass::DICT_BACKED) {
BoxedDict* d = (BoxedDict*)this->attr_list->attrs[0];
for (auto&& e : d->d) {
if (PyString_Check(e.first.value) && first_check_func(PyString_AsString(e.first.value))) {
AUTO_DECREF(e.second);
e.second = incref(None);
}
}
for (auto&& e : d->d) {
if (PyString_Check(e.first.value) && second_check_func(PyString_AsString(e.first.value))) {
AUTO_DECREF(e.second);
e.second = incref(None);
}
}
return;
}
RELEASE_ASSERT(hcls->type == HiddenClass::NORMAL || hcls->type == HiddenClass::SINGLETON, "");
auto attr_list = this->attr_list;
auto attr_list_size = hcls->attributeArraySize();
for (auto&& p : hcls->getStrAttrOffsets()) {
const char* s = p.first->c_str();
if (s[0] == '_' && s[1] != '_') {
if (first_check_func(s)) {
int idx = p.second;
Box* b = attr_list->attrs[idx];
attr_list->attrs[idx] = incref(None);
......@@ -1374,7 +1393,7 @@ void HCAttrs::moduleClear() noexcept {
for (auto&& p : hcls->getStrAttrOffsets()) {
const char* s = p.first->c_str();
if (s[0] != '_' || strcmp(s, "__builtins__") != 0) {
if (second_check_func(s)) {
int idx = p.second;
Box* b = attr_list->attrs[idx];
attr_list->attrs[idx] = incref(None);
......@@ -4648,12 +4667,9 @@ Box* callFunc(BoxedFunctionBase* func, CallRewriteArgs* rewrite_args, ArgPassSpe
if (num_output_args > 3) {
int size = (num_output_args - 3) * sizeof(Box*);
oargs = (Box**)alloca(size);
memset(&oargs[0], 0, size);
oargs_owned = (bool*)alloca((num_output_args - 3) * sizeof(bool));
#ifndef NDEBUG
memset(&oargs[0], 0, size);
#endif
}
try {
......@@ -6865,7 +6881,7 @@ Box* _typeNew(BoxedClass* metatype, BoxedString* name, BoxedTuple* bases, BoxedD
for (size_t i = 0; i < slots.size(); i++) {
Box* slot_name = slots[i];
if (PyUnicode_Check(slot_name)) {
slots[i] = _PyUnicode_AsDefaultEncodedString(slot_name, NULL);
slots[i] = xincref(_PyUnicode_AsDefaultEncodedString(slot_name, NULL));
if (!slots[i])
throwCAPIException();
Py_DECREF(slot_name);
......
......@@ -40,6 +40,7 @@
#include "runtime/dict.h"
#include "runtime/hiddenclass.h"
#include "runtime/ics.h"
#include "runtime/import.h"
#include "runtime/inline/list.h"
#include "runtime/iterobject.h"
#include "runtime/list.h"
......@@ -834,7 +835,7 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
bool rewrite_success = false;
static ParamNames param_names({ "", "string", "encoding", "errors" }, "", "");
static Box* defaults[3] = { NULL, NULL, NULL };
Box* oargs[1];
Box* oargs[1] = { NULL };
bool oargs_owned[1];
rearrangeArguments(paramspec, &param_names, "unicode", defaults, rewrite_args, rewrite_success, argspec, arg1,
......@@ -2864,7 +2865,6 @@ BORROWED(Box*) Box::getAttrWrapper() {
}
extern "C" BORROWED(PyObject*) PyObject_GetAttrWrapper(PyObject* obj) noexcept {
assert(0 && "check refcounting");
return obj->getAttrWrapper();
}
......@@ -4976,6 +4976,12 @@ extern "C" void Py_Finalize() noexcept {
assert_refs = false;
}
if (imported_foreign_cextension) {
if (VERBOSITY() && _Py_RefTotal)
fprintf(stderr, "[Leaked references but we did load foreign C extensions']\n");
assert_refs = false;
}
if (assert_refs) {
#ifdef Py_TRACE_REFS
if (_Py_RefTotal != 0)
......
......@@ -20,18 +20,3 @@ diff -ur M2Crypto-0.21.1.orig/SWIG/_lib.i ./SWIG/_lib.i
new_style_callback = 1;
}
} else {
diff -ur M2Crypto-0.21.1/M2Crypto/m2urllib2.py ./M2Crypto/m2urllib2.py
--- M2Crypto-0.21.1/M2Crypto/m2urllib2.py 2011-01-15 19:10:05.000000000 +0000
+++ ./M2Crypto/m2urllib2.py 2016-02-10 14:36:12.091812337 +0000
@@ -97,6 +97,11 @@
# out of socket._fileobject() and into a base class.
r.recv = r.read
+
+ # Pyston change: our socket implementation needs this functions
+ r._reuse = lambda: None
+ r._drop = lambda: None
+
fp = _closing_fileobject(r)
resp = addinfourl(fp, r.msg, req.get_full_url())
......@@ -42,7 +42,7 @@ def install_and_test_lxml():
env["CFLAGS"] = "-DSWIG_PYTHON_SLOW_GETSET_THIS"
subprocess.check_call([PYTHON_EXE, "setup.py", "install"], cwd=M2CRYPTO_DIR, env=env)
expected = [{'ran': 235, 'failures': 1, 'errors': 7, 'skipped': 2}]
expected = [{'ran': 235, 'errors': 5, 'skipped': 2}]
run_test([PYTHON_EXE, "setup.py", "test"], cwd=M2CRYPTO_DIR, expected=expected)
create_virtenv(ENV_NAME, None, force_create = True)
......
diff -ur cffi-1.2.1_orig/c/_cffi_backend.c cffi-1.2.1/c/_cffi_backend.c
--- cffi-1.2.1_orig/c/_cffi_backend.c 2016-02-22 18:48:06.861772302 +0000
+++ cffi-1.2.1/c/_cffi_backend.c 2016-02-24 18:57:47.479889228 +0000
@@ -5065,6 +5065,10 @@
cd->c_weakreflist = NULL;
PyObject_GC_Track(cd);
+ // Pyston change: HACK which leaks mem but seems necessary at the moment to prevent crashes with our GC
+ PyGC_AddRoot((PyObject*)cd);
+ PyGC_AddRoot((PyObject*)infotuple);
+
cif_descr = (cif_description_t *)ct->ct_extra;
if (cif_descr == NULL) {
PyErr_Format(PyExc_NotImplementedError,
@@ -5572,7 +5576,9 @@
return NULL;
}
x = (PyObject *)(raw + 42);
- if (Py_REFCNT(x) <= 0) {
+ // Pyston change:
+ // if (Py_REFCNT(x) <= 0) {
+ if (0) {
Py_FatalError("ffi.from_handle() detected that the address passed "
"points to garbage. If it is really the result of "
"ffi.new_handle(), then the Python object has already "
diff -ur cffi-1.2.1_orig/c/cglob.c cffi-1.2.1/c/cglob.c
--- cffi-1.2.1_orig/c/cglob.c 2016-02-22 18:48:06.853772302 +0000
+++ cffi-1.2.1/c/cglob.c 2016-02-25 11:02:26.319738004 +0000
......
# expected: reffail
import os, sys, subprocess, shutil
sys.path.append(os.path.dirname(__file__) + "/../lib")
......
......@@ -33,9 +33,8 @@ def install_and_test_lxml():
subprocess.check_call([PYTHON_EXE, "setup.py", "build_ext", "-i", "--with-cython"], cwd=LXML_DIR)
# We currently don't run the objectify tests because the assume that the python impl use refcounting.
expected = [{'ran': 1188, 'failures': 3, 'errors': 1}]
run_test([PYTHON_EXE, "test.py", "!.*test_objectify.py"], cwd=LXML_DIR, expected=expected)
expected = [{'ran': 1381, 'failures': 3, 'errors': 1}]
run_test([PYTHON_EXE, "test.py"], cwd=LXML_DIR, expected=expected)
create_virtenv(ENV_NAME, None, force_create = True)
install_and_test_lxml()
......@@ -17,5 +17,5 @@ import subprocess
subprocess.check_call(["sed", "-i", 's/\\(def test_digest.*\\)/\\1\\n return/',
os.path.join(PYOPENSSL_DIR, "test", "test_crypto.py")])
expected = [{'ran': 247, 'errors': 1}]
expected = [{'ran': 438}]
run_test([NOSETESTS_EXE], cwd=PYOPENSSL_DIR, expected=expected)
From e0257ba4efd903da2a0f1909d21d51ff1799a3c6 Mon Sep 17 00:00:00 2001
From eaf300b61a56af151e93aa51803e6a61a0f8afee Mon Sep 17 00:00:00 2001
From: Marius Wachtler <undingen@gmail.com>
Date: Tue, 9 Jun 2015 19:26:44 +0200
Subject: [PATCH] Pyston change: we don't support custom traceback entries yet
Date: Fri, 6 May 2016 16:19:50 +0100
Subject: [PATCH] [PATCH] Pyston change: make cython work with pyston
---
Cython/Compiler/ExprNodes.py | 9 +++++++++
Cython/Compiler/ModuleNode.py | 8 ++++++--
Cython/Utility/CythonFunction.c | 4 +++-
Cython/Utility/Exceptions.c | 7 ++++++-
Cython/Utility/Generator.c | 41 ++++++++++++++++++++++++++++------------
Cython/Utility/ModuleSetupCode.c | 2 +-
6 files changed, 54 insertions(+), 17 deletions(-)
Cython/Compiler/ExprNodes.py | 9 +++++++++
Cython/Utility/CythonFunction.c | 4 +++-
Cython/Utility/Exceptions.c | 4 +++-
Cython/Utility/ModuleSetupCode.c | 2 +-
4 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/Cython/Compiler/ExprNodes.py b/Cython/Compiler/ExprNodes.py
index f99ec6e..7ab41f3 100644
......@@ -38,26 +36,6 @@ index f99ec6e..7ab41f3 100644
def analyse_types(self, env):
if self.binding:
diff --git a/Cython/Compiler/ModuleNode.py b/Cython/Compiler/ModuleNode.py
index 4785858..699cd15 100644
--- a/Cython/Compiler/ModuleNode.py
+++ b/Cython/Compiler/ModuleNode.py
@@ -1399,9 +1399,13 @@ class ModuleNode(Nodes.Node, Nodes.BlockNode):
code.putln("{")
code.putln("PyObject *etype, *eval, *etb;")
code.putln("PyErr_Fetch(&etype, &eval, &etb);")
- code.putln("++Py_REFCNT(o);")
+ # Pyston change:
+ # code.putln("++Py_REFCNT(o);")
+ code.putln("Py_INCREF(o);")
code.putln("%s(o);" % entry.func_cname)
- code.putln("--Py_REFCNT(o);")
+ # Pyston change:
+ # code.putln("--Py_REFCNT(o);")
+ code.putln("Py_DECREF(o);")
code.putln("PyErr_Restore(etype, eval, etb);")
code.putln("}")
diff --git a/Cython/Utility/CythonFunction.c b/Cython/Utility/CythonFunction.c
index 9cc38f0..ab05ad1 100644
--- a/Cython/Utility/CythonFunction.c
......@@ -74,10 +52,10 @@ index 9cc38f0..ab05ad1 100644
// PyPy does not have this function
static PyObject * __Pyx_CyFunction_Call(PyObject *func, PyObject *arg, PyObject *kw) {
diff --git a/Cython/Utility/Exceptions.c b/Cython/Utility/Exceptions.c
index 354a776..8af3cb7 100644 static void __Pyx_AddTraceback(const char *funcname, int c_line,
index 354a776..567970d 100644
--- a/Cython/Utility/Exceptions.c
+++ b/Cython/Utility/Exceptions.c
@@ -528,7 +528,9 @@
@@ -528,7 +528,9 @@ static void __Pyx_AddTraceback(const char *funcname, int c_line,
0 /*PyObject *locals*/
);
if (!py_frame) goto bad;
......@@ -88,100 +66,6 @@ index 354a776..8af3cb7 100644 static void __Pyx_AddTraceback(const char *funcnam
PyTraceBack_Here(py_frame);
bad:
Py_XDECREF(py_code);
diff --git a/Cython/Utility/Generator.c b/Cython/Utility/Generator.c
index 0310570..70e550c 100644
--- a/Cython/Utility/Generator.c
+++ b/Cython/Utility/Generator.c
@@ -43,7 +43,9 @@ static void __Pyx_Generator_Replace_StopIteration(void) {
//////////////////// Generator.proto ////////////////////
#define __Pyx_Generator_USED
#include <structmember.h>
-#include <frameobject.h>
+
+// Pyston change:
+// #include <frameobject.h>
typedef PyObject *(*__pyx_generator_body_t)(PyObject *, PyObject *);
@@ -473,6 +475,9 @@ static int __Pyx_Generator_clear(PyObject *self) {
return 0;
}
+// Pyston change: add forward decl
+static void __Pyx_Generator_del(PyObject *self);
+
static void __Pyx_Generator_dealloc(PyObject *self) {
__pyx_GeneratorObject *gen = (__pyx_GeneratorObject *) self;
@@ -486,8 +491,10 @@ static void __Pyx_Generator_dealloc(PyObject *self) {
#if PY_VERSION_HEX >= 0x030400a1
if (PyObject_CallFinalizerFromDealloc(self))
#else
- Py_TYPE(gen)->tp_del(self);
- if (self->ob_refcnt > 0)
+ // Pyston change: call __Pyx_Generator_del directly and assume obj resurrected
+ // Py_TYPE(gen)->tp_del(self);
+ // if (self->ob_refcnt > 0)
+ __Pyx_Generator_del(self);
#endif
{
// resurrected. :(
@@ -509,9 +516,10 @@ static void __Pyx_Generator_del(PyObject *self) {
return ;
#if PY_VERSION_HEX < 0x030400a1
- // Temporarily resurrect the object.
- assert(self->ob_refcnt == 0);
- self->ob_refcnt = 1;
+ // Pyston change:
+ // // Temporarily resurrect the object.
+ // assert(self->ob_refcnt == 0);
+ // self->ob_refcnt = 1;
#endif
// Save the current exception, if any.
@@ -530,18 +538,25 @@ static void __Pyx_Generator_del(PyObject *self) {
#if PY_VERSION_HEX < 0x030400a1
// Undo the temporary resurrection; can't use DECREF here, it would
// cause a recursive call.
- assert(self->ob_refcnt > 0);
- if (--self->ob_refcnt == 0) {
- // this is the normal path out
- return;
- }
+
+ // Pyston change:
+ // assert(self->ob_refcnt > 0);
+ // if (--self->ob_refcnt == 0) {
+ // // this is the normal path out
+ // return;
+ // }
// close() resurrected it! Make it look like the original Py_DECREF
// never happened.
{
+// Pyston change:
+#if 0
Py_ssize_t refcnt = self->ob_refcnt;
_Py_NewReference(self);
self->ob_refcnt = refcnt;
+#else
+ _Py_NewReference(self);
+#endif
}
#if CYTHON_COMPILING_IN_CPYTHON
assert(PyType_IS_GC(self->ob_type) &&
@@ -692,7 +707,9 @@ static PyTypeObject __pyx_GeneratorType_type = {
#if PY_VERSION_HEX >= 0x030400a1
0, /*tp_del*/
#else
- __Pyx_Generator_del, /*tp_del*/
+ // Pyston change: we don't currently support types which set a tp_dealloc and tp_del
+ // __Pyx_Generator_del, /*tp_del*/
+ 0,
#endif
0, /*tp_version_tag*/
#if PY_VERSION_HEX >= 0x030400a1
diff --git a/Cython/Utility/ModuleSetupCode.c b/Cython/Utility/ModuleSetupCode.c
index 6477fb2..75dcdda 100644
--- a/Cython/Utility/ModuleSetupCode.c
......@@ -198,4 +82,3 @@ index 6477fb2..75dcdda 100644
--
1.9.1
# expected: reffail
import os
import signal
import subprocess
......
diff --git a/numpy/core/include/numpy/ndarrayobject.h b/numpy/core/include/numpy/ndarrayobject.h
index fbaaeac..cb4adbb 100644
--- a/numpy/core/include/numpy/ndarrayobject.h
+++ b/numpy/core/include/numpy/ndarrayobject.h
@@ -117,7 +117,8 @@ extern "C" CONFUSE_EMACS
#define PyArray_FILLWBYTE(obj, val) memset(PyArray_DATA(obj), val, \
PyArray_NBYTES(obj))
-#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+//#define PyArray_REFCOUNT(obj) (((PyObject *)(obj))->ob_refcnt)
+#define PyArray_REFCOUNT(obj) 0
#define NPY_REFCOUNT PyArray_REFCOUNT
#define NPY_MAX_ELSIZE (2 * NPY_SIZEOF_LONGDOUBLE)
diff --git a/numpy/core/include/numpy/ndarraytypes.h b/numpy/core/include/numpy/ndarraytypes.h
index 8403ee2..0bc2d4d 100644
--- a/numpy/core/include/numpy/ndarraytypes.h
+++ b/numpy/core/include/numpy/ndarraytypes.h
@@ -931,11 +931,18 @@ typedef int (PyArray_FinalizeFunc)(PyArrayObject *, PyObject *);
#if NPY_ALLOW_THREADS
#define NPY_BEGIN_ALLOW_THREADS Py_BEGIN_ALLOW_THREADS
#define NPY_END_ALLOW_THREADS Py_END_ALLOW_THREADS
+#define NPY_BEGIN_THREADS do {_save = NULL;} while (0);
+/*
#define NPY_BEGIN_THREADS do {_save = PyEval_SaveThread();} while (0);
+*/
#define NPY_END_THREADS do { if (_save) \
{ PyEval_RestoreThread(_save); _save = NULL;} } while (0);
#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
+ { _save = NULL;} } while (0);
+/*
+#define NPY_BEGIN_THREADS_THRESHOLDED(loop_size) do { if (loop_size > 500) \
{ _save = PyEval_SaveThread();} } while (0);
+*/
#define NPY_BEGIN_THREADS_DESCR(dtype) \
do {if (!(PyDataType_FLAGCHK(dtype, NPY_NEEDS_PYAPI))) \
diff --git a/numpy/core/src/multiarray/arraytypes.c.src b/numpy/core/src/multiarray/arraytypes.c.src
index 5a1e2f4..6f1cd62 100644
--- a/numpy/core/src/multiarray/arraytypes.c.src
+++ b/numpy/core/src/multiarray/arraytypes.c.src
@@ -4469,6 +4469,11 @@ set_typeinfo(PyObject *dict)
PyArray_Descr *dtype;
PyObject *cobj, *key;
+ /* Pyston change: deal with static nonheap objects */
+ for (i = 0; i < 24; i++) {
+ PyGC_AddNonHeapRoot((PyObject*)_builtin_descrs[i], sizeof(PyArray_Descr));
+ }
+
/*
* Add cast functions for the new types
*/
diff --git a/numpy/core/src/multiarray/compiled_base.c b/numpy/core/src/multiarray/compiled_base.c
index 8ffeeda..5d43aab 100644
--- a/numpy/core/src/multiarray/compiled_base.c
......@@ -124,52 +71,6 @@ index d025901..27c8718 100644
}
PyDict_SetItem(fields, title, tup);
}
diff --git a/numpy/core/src/multiarray/scalartypes.c.src b/numpy/core/src/multiarray/scalartypes.c.src
index b5e0fde..13784b3 100644
--- a/numpy/core/src/multiarray/scalartypes.c.src
+++ b/numpy/core/src/multiarray/scalartypes.c.src
@@ -4060,6 +4060,10 @@ static void init_basetypes(void);
NPY_NO_EXPORT void
initialize_numeric_types(void)
{
+ /* Pyston change: deal with static nonheap objects */
+ PyGC_AddNonHeapRoot((PyObject*)&_PyArrayScalar_BoolValues[0], sizeof(PyBoolScalarObject));
+ PyGC_AddNonHeapRoot((PyObject*)&_PyArrayScalar_BoolValues[1], sizeof(PyBoolScalarObject));
+
init_basetypes();
PyGenericArrType_Type.tp_dealloc = (destructor)gentype_dealloc;
PyGenericArrType_Type.tp_as_number = &gentype_as_number;
diff --git a/numpy/core/src/umath/test_rational.c.src b/numpy/core/src/umath/test_rational.c.src
index b0c06e1..191fbed 100644
--- a/numpy/core/src/umath/test_rational.c.src
+++ b/numpy/core/src/umath/test_rational.c.src
@@ -1189,6 +1189,10 @@ PyMODINIT_FUNC inittest_rational(void) {
npyrational_arrfuncs.fillwithscalar = npyrational_fillwithscalar;
/* Left undefined: scanfunc, fromstr, sort, argsort */
Py_TYPE(&npyrational_descr) = &PyArrayDescr_Type;
+
+ /* Pyston change: deal with static nonheap objects */
+ PyGC_AddNonHeapRoot((PyObject*)&npyrational_descr, sizeof(PyArray_Descr));
+
npy_rational = PyArray_RegisterDataType(&npyrational_descr);
if (npy_rational<0) {
goto fail;
diff --git a/numpy/core/src/umath/ufunc_object.c b/numpy/core/src/umath/ufunc_object.c
index 7797731..93edc66 100644
--- a/numpy/core/src/umath/ufunc_object.c
+++ b/numpy/core/src/umath/ufunc_object.c
@@ -4345,9 +4345,11 @@ ufunc_generic_call(PyUFuncObject *ufunc, PyObject *args, PyObject *kwds)
}
fail:
+ /* Causes compiler CRASH wtf
for (i = ufunc->nin; i < ufunc->nargs; i++) {
Py_XDECREF(mps[i]);
}
+ */
return NULL;
}
diff --git a/numpy/core/tests/test_records.py b/numpy/core/tests/test_records.py
index 7a18f29..a8d4e4b 100644
--- a/numpy/core/tests/test_records.py
......
# expected: reffail
import os
import sys
import subprocess
......
# expected: reffail
import subprocess, sys, os, shutil, StringIO
sys.path.append(os.path.dirname(__file__) + "/../lib")
import test_helper
......
# expected: reffail
import os
import sys
import subprocess
......
# expected: reffail
import os
import sys
import subprocess
......
# skip-if: True
# this currently prints the wrong result in a release build
# run_args: -n
# statcheck: noninit_count('slowpath_member_descriptor_get') <= 1500
......
......@@ -19,3 +19,4 @@ m = types.ModuleType("foo", u"bar")
print m.__doc__, type(m.__doc__)
m.__init__("bar", "baz")
print m.__doc__, type(m.__doc__)
m.__dict__[u"\u20ac"] = "test"
# this used to crash the bjit
for i in range(1000):
s = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99}
......@@ -6,6 +6,8 @@ CMAKE_ARGS="-GNinja -DTEST_THREADS=4 $TRAVIS_BUILD_DIR -DCMAKE_BUILD_TYPE=${TRAV
if [ "${TRAVIS_BUILD_TYPE}" = "Release" ]; then
CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_EXTRA_TESTS=ON"
else
CMAKE_ARGS="${CMAKE_ARGS} -DENABLE_REF_DEBUG=ON"
fi
cmake ${CMAKE_ARGS}
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