Commit b322d2b2 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #658 from kmod/perf7

fastpath investigations
parents 96674bed cab7c2dc
...@@ -177,7 +177,7 @@ if(ENABLE_OPROFILE) ...@@ -177,7 +177,7 @@ if(ENABLE_OPROFILE)
set(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} opagent) set(OPTIONAL_LIBRARIES ${OPTIONAL_LIBRARIES} opagent)
endif() endif()
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wreturn-type -Wno-sign-compare -Wno-unused -Wno-unused-parameter -fno-omit-frame-pointer") set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -Werror -Wreturn-type -Wno-sign-compare -Wno-unused -Wno-unused-parameter -fno-omit-frame-pointer -g")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fexceptions -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -Woverloaded-virtual -Wno-invalid-offsetof -Wcast-qual -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wmissing-include-dirs -Wstrict-overflow=5 -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wmissing-field-initializers -Wredundant-decls -Winline -Wint-to-pointer-cast -Wlong-long -Wvla -Wno-attributes -g") set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${CMAKE_C_FLAGS} -std=c++11 -fno-rtti -fexceptions -fvisibility-inlines-hidden -ffunction-sections -fdata-sections -Woverloaded-virtual -Wno-invalid-offsetof -Wcast-qual -Wno-sign-conversion -Wnon-virtual-dtor -Winit-self -Wmissing-include-dirs -Wstrict-overflow=5 -Wpointer-arith -Wtype-limits -Wwrite-strings -Wempty-body -Waggregate-return -Wmissing-field-initializers -Wredundant-decls -Winline -Wint-to-pointer-cast -Wlong-long -Wvla -Wno-attributes -g")
set(CLANG_FLAGS "${CLANG_FLAGS} -Wimplicit-int -Wstrict-prototypes -Wold-style-definition -Wnested-externs -Wpointer-to-int-cast -Wno-mismatched-tags -Wno-extern-c-compat") set(CLANG_FLAGS "${CLANG_FLAGS} -Wimplicit-int -Wstrict-prototypes -Wold-style-definition -Wnested-externs -Wpointer-to-int-cast -Wno-mismatched-tags -Wno-extern-c-compat")
......
...@@ -19,6 +19,8 @@ USE_CLANG := 1 ...@@ -19,6 +19,8 @@ USE_CLANG := 1
USE_CCACHE := 1 USE_CCACHE := 1
USE_DISTCC := 0 USE_DISTCC := 0
PYPY := pypy
ENABLE_VALGRIND := 0 ENABLE_VALGRIND := 0
GDB := gdb GDB := gdb
...@@ -1024,7 +1026,7 @@ $(call make_target,_gcc) ...@@ -1024,7 +1026,7 @@ $(call make_target,_gcc)
nosearch_runpy_% nosearch_pyrun_%: %.py ext_python nosearch_runpy_% nosearch_pyrun_%: %.py ext_python
$(VERB) PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7 zsh -c 'time python $<' $(VERB) PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7 zsh -c 'time python $<'
nosearch_pypyrun_%: %.py ext_python nosearch_pypyrun_%: %.py ext_python
$(VERB) PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7 zsh -c 'time pypy $<' $(VERB) PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7 zsh -c 'time $(PYPY) $<'
$(call make_search,runpy_%) $(call make_search,runpy_%)
$(call make_search,pyrun_%) $(call make_search,pyrun_%)
$(call make_search,pypyrun_%) $(call make_search,pypyrun_%)
......
...@@ -1185,7 +1185,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/ ...@@ -1185,7 +1185,7 @@ xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx*/
#define PySequence_Fast_ITEMS(sf) \ #define PySequence_Fast_ITEMS(sf) \
(PyList_Check(sf) ? (PyList_Items(sf)) \ (PyList_Check(sf) ? (PyList_Items(sf)) \
: (PyTuple_Items(sf))) : ((PyTupleObject *)(sf))->ob_item)
/* Return a pointer to the underlying item array for /* Return a pointer to the underlying item array for
an object retured by PySequence_Fast */ an object retured by PySequence_Fast */
......
...@@ -22,8 +22,6 @@ inserted in the tuple. Similarly, PyTuple_GetItem does not increment the ...@@ -22,8 +22,6 @@ inserted in the tuple. Similarly, PyTuple_GetItem does not increment the
returned item's reference count. returned item's reference count.
*/ */
// Pyston change: this is not the format we're using (but maybe it should be)
#if 0
typedef struct { typedef struct {
PyObject_VAR_HEAD PyObject_VAR_HEAD
PyObject *ob_item[1]; PyObject *ob_item[1];
...@@ -33,9 +31,6 @@ typedef struct { ...@@ -33,9 +31,6 @@ typedef struct {
* the tuple is not yet visible outside the function that builds it. * the tuple is not yet visible outside the function that builds it.
*/ */
} PyTupleObject; } PyTupleObject;
#endif
struct _PyTupleObject;
typedef struct _PyTupleObject PyTupleObject;
// Pyston change: this is no longer a static object // Pyston change: this is no longer a static object
PyAPI_DATA(PyTypeObject*) tuple_cls; PyAPI_DATA(PyTypeObject*) tuple_cls;
...@@ -54,18 +49,11 @@ PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t) PYSTON_NOEXCEPT; ...@@ -54,18 +49,11 @@ PyAPI_FUNC(int) _PyTuple_Resize(PyObject **, Py_ssize_t) PYSTON_NOEXCEPT;
PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...) PYSTON_NOEXCEPT; PyAPI_FUNC(PyObject *) PyTuple_Pack(Py_ssize_t, ...) PYSTON_NOEXCEPT;
PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *) PYSTON_NOEXCEPT; PyAPI_FUNC(void) _PyTuple_MaybeUntrack(PyObject *) PYSTON_NOEXCEPT;
// Pyston addition:
PyAPI_FUNC(PyObject **) PyTuple_Items(PyObject *) PYSTON_NOEXCEPT;
/* Macro, trading safety for speed */ /* Macro, trading safety for speed */
// Pyston changes: these aren't direct macros any more [they potentially could be though] #define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
#define PyTuple_GET_ITEM(op, i) PyTuple_GetItem(op, i) #define PyTuple_GET_SIZE(op) Py_SIZE(op)
#define PyTuple_GET_SIZE(op) PyTuple_Size(op)
//#define PyTuple_GET_ITEM(op, i) (((PyTupleObject *)(op))->ob_item[i])
//#define PyTuple_GET_SIZE(op) Py_SIZE(op)
/* Macro, *only* to be used to fill in brand new tuples */ /* Macro, *only* to be used to fill in brand new tuples */
#define PyTuple_SET_ITEM(op, i, v) PyTuple_SetItem((PyObject*)op, i, v) #define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
//#define PyTuple_SET_ITEM(op, i, v) (((PyTupleObject *)(op))->ob_item[i] = v)
PyAPI_FUNC(int) PyTuple_ClearFreeList(void) PYSTON_NOEXCEPT; PyAPI_FUNC(int) PyTuple_ClearFreeList(void) PYSTON_NOEXCEPT;
...@@ -73,4 +61,3 @@ PyAPI_FUNC(int) PyTuple_ClearFreeList(void) PYSTON_NOEXCEPT; ...@@ -73,4 +61,3 @@ PyAPI_FUNC(int) PyTuple_ClearFreeList(void) PYSTON_NOEXCEPT;
} }
#endif #endif
#endif /* !Py_TUPLEOBJECT_H */ #endif /* !Py_TUPLEOBJECT_H */
...@@ -263,6 +263,8 @@ void Rewriter::assertArgsInPlace() { ...@@ -263,6 +263,8 @@ void Rewriter::assertArgsInPlace() {
} }
void RewriterVar::addGuard(uint64_t val) { void RewriterVar::addGuard(uint64_t val) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* val_var = rewriter->loadConst(val); RewriterVar* val_var = rewriter->loadConst(val);
rewriter->addAction([=]() { rewriter->_addGuard(this, val_var); }, { this, val_var }, ActionType::GUARD); rewriter->addAction([=]() { rewriter->_addGuard(this, val_var); }, { this, val_var }, ActionType::GUARD);
} }
...@@ -291,6 +293,8 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) { ...@@ -291,6 +293,8 @@ void Rewriter::_addGuard(RewriterVar* var, RewriterVar* val_constant) {
} }
void RewriterVar::addGuardNotEq(uint64_t val) { void RewriterVar::addGuardNotEq(uint64_t val) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* val_var = rewriter->loadConst(val); RewriterVar* val_var = rewriter->loadConst(val);
rewriter->addAction([=]() { rewriter->_addGuardNotEq(this, val_var); }, { this, val_var }, ActionType::GUARD); rewriter->addAction([=]() { rewriter->_addGuardNotEq(this, val_var); }, { this, val_var }, ActionType::GUARD);
} }
...@@ -319,6 +323,8 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) { ...@@ -319,6 +323,8 @@ void Rewriter::_addGuardNotEq(RewriterVar* var, RewriterVar* val_constant) {
} }
void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) { void RewriterVar::addAttrGuard(int offset, uint64_t val, bool negate) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
if (!attr_guards.insert(std::make_tuple(offset, val, negate)).second) if (!attr_guards.insert(std::make_tuple(offset, val, negate)).second)
return; // duplicate guard detected return; // duplicate guard detected
RewriterVar* val_var = rewriter->loadConst(val); RewriterVar* val_var = rewriter->loadConst(val);
...@@ -369,6 +375,8 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons ...@@ -369,6 +375,8 @@ void Rewriter::_addAttrGuard(RewriterVar* var, int offset, RewriterVar* val_cons
} }
RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType type) { RewriterVar* RewriterVar::getAttr(int offset, Location dest, assembler::MovType type) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttr(result, this, offset, dest, type); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttr(result, this, offset, dest, type); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -394,6 +402,8 @@ void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Locat ...@@ -394,6 +402,8 @@ void Rewriter::_getAttr(RewriterVar* result, RewriterVar* ptr, int offset, Locat
} }
RewriterVar* RewriterVar::getAttrDouble(int offset, Location dest) { RewriterVar* RewriterVar::getAttrDouble(int offset, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttrDouble(result, this, offset, dest); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttrDouble(result, this, offset, dest); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -412,6 +422,8 @@ void Rewriter::_getAttrDouble(RewriterVar* result, RewriterVar* ptr, int offset, ...@@ -412,6 +422,8 @@ void Rewriter::_getAttrDouble(RewriterVar* result, RewriterVar* ptr, int offset,
} }
RewriterVar* RewriterVar::getAttrFloat(int offset, Location dest) { RewriterVar* RewriterVar::getAttrFloat(int offset, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_getAttrFloat(result, this, offset, dest); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_getAttrFloat(result, this, offset, dest); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -433,6 +445,8 @@ void Rewriter::_getAttrFloat(RewriterVar* result, RewriterVar* ptr, int offset, ...@@ -433,6 +445,8 @@ void Rewriter::_getAttrFloat(RewriterVar* result, RewriterVar* ptr, int offset,
} }
RewriterVar* RewriterVar::cmp(AST_TYPE::AST_TYPE cmp_type, RewriterVar* other, Location dest) { RewriterVar* RewriterVar::cmp(AST_TYPE::AST_TYPE cmp_type, RewriterVar* other, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_cmp(result, this, cmp_type, other, dest); }, { this, other }, rewriter->addAction([=]() { rewriter->_cmp(result, this, cmp_type, other, dest); }, { this, other },
ActionType::NORMAL); ActionType::NORMAL);
...@@ -466,6 +480,8 @@ void Rewriter::_cmp(RewriterVar* result, RewriterVar* v1, AST_TYPE::AST_TYPE cmp ...@@ -466,6 +480,8 @@ void Rewriter::_cmp(RewriterVar* result, RewriterVar* v1, AST_TYPE::AST_TYPE cmp
} }
RewriterVar* RewriterVar::toBool(Location dest) { RewriterVar* RewriterVar::toBool(Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = rewriter->createNewVar(); RewriterVar* result = rewriter->createNewVar();
rewriter->addAction([=]() { rewriter->_toBool(result, this, dest); }, { this }, ActionType::NORMAL); rewriter->addAction([=]() { rewriter->_toBool(result, this, dest); }, { this }, ActionType::NORMAL);
return result; return result;
...@@ -487,6 +503,8 @@ void Rewriter::_toBool(RewriterVar* result, RewriterVar* var, Location dest) { ...@@ -487,6 +503,8 @@ void Rewriter::_toBool(RewriterVar* result, RewriterVar* var, Location dest) {
} }
void RewriterVar::setAttr(int offset, RewriterVar* val) { void RewriterVar::setAttr(int offset, RewriterVar* val) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
rewriter->addAction([=]() { rewriter->_setAttr(this, offset, val); }, { this, val }, ActionType::MUTATION); rewriter->addAction([=]() { rewriter->_setAttr(this, offset, val); }, { this, val }, ActionType::MUTATION);
} }
...@@ -656,6 +674,8 @@ void Rewriter::_trap() { ...@@ -656,6 +674,8 @@ void Rewriter::_trap() {
} }
RewriterVar* Rewriter::loadConst(int64_t val, Location dest) { RewriterVar* Rewriter::loadConst(int64_t val, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar*& const_loader_var = const_loader.constToVar[val]; RewriterVar*& const_loader_var = const_loader.constToVar[val];
if (!const_loader_var) { if (!const_loader_var) {
const_loader_var = createNewConstantVar(val); const_loader_var = createNewConstantVar(val);
...@@ -664,12 +684,16 @@ RewriterVar* Rewriter::loadConst(int64_t val, Location dest) { ...@@ -664,12 +684,16 @@ RewriterVar* Rewriter::loadConst(int64_t val, Location dest) {
} }
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr) { RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar::SmallVector args; RewriterVar::SmallVector args;
RewriterVar::SmallVector args_xmm; RewriterVar::SmallVector args_xmm;
return call(has_side_effects, func_addr, args, args_xmm); return call(has_side_effects, func_addr, args, args_xmm);
} }
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0) { RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar::SmallVector args; RewriterVar::SmallVector args;
RewriterVar::SmallVector args_xmm; RewriterVar::SmallVector args_xmm;
args.push_back(arg0); args.push_back(arg0);
...@@ -677,6 +701,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* ...@@ -677,6 +701,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
} }
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1) { RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar::SmallVector args; RewriterVar::SmallVector args;
RewriterVar::SmallVector args_xmm; RewriterVar::SmallVector args_xmm;
args.push_back(arg0); args.push_back(arg0);
...@@ -686,6 +712,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* ...@@ -686,6 +712,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1, RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1,
RewriterVar* arg2) { RewriterVar* arg2) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar::SmallVector args; RewriterVar::SmallVector args;
RewriterVar::SmallVector args_xmm; RewriterVar::SmallVector args_xmm;
args.push_back(arg0); args.push_back(arg0);
...@@ -696,6 +724,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* ...@@ -696,6 +724,8 @@ RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar*
RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1, RewriterVar* Rewriter::call(bool has_side_effects, void* func_addr, RewriterVar* arg0, RewriterVar* arg1,
RewriterVar* arg2, RewriterVar* arg3) { RewriterVar* arg2, RewriterVar* arg3) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar::SmallVector args; RewriterVar::SmallVector args;
RewriterVar::SmallVector args_xmm; RewriterVar::SmallVector args_xmm;
args.push_back(arg0); args.push_back(arg0);
...@@ -903,6 +933,8 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, void* func_addr ...@@ -903,6 +933,8 @@ void Rewriter::_call(RewriterVar* result, bool has_side_effects, void* func_addr
} }
void Rewriter::abort() { void Rewriter::abort() {
STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(!finished); assert(!finished);
finished = true; finished = true;
rewrite->abort(); rewrite->abort();
...@@ -944,6 +976,8 @@ void RewriterVar::releaseIfNoUses() { ...@@ -944,6 +976,8 @@ void RewriterVar::releaseIfNoUses() {
} }
void Rewriter::commit() { void Rewriter::commit() {
STAT_TIMER(t0, "us_timer_rewriter", 10);
assert(!finished); assert(!finished);
initPhaseEmitting(); initPhaseEmitting();
...@@ -1173,6 +1207,8 @@ bool Rewriter::finishAssembly(ICSlotInfo* picked_slot, int continue_offset) { ...@@ -1173,6 +1207,8 @@ bool Rewriter::finishAssembly(ICSlotInfo* picked_slot, int continue_offset) {
} }
void Rewriter::commitReturning(RewriterVar* var) { void Rewriter::commitReturning(RewriterVar* var) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
addAction([=]() { addAction([=]() {
var->getInReg(getReturnDestination(), true /* allow_constant_in_reg */); var->getInReg(getReturnDestination(), true /* allow_constant_in_reg */);
var->bumpUse(); var->bumpUse();
...@@ -1201,6 +1237,8 @@ Location Rewriter::allocScratch() { ...@@ -1201,6 +1237,8 @@ Location Rewriter::allocScratch() {
} }
RewriterVar* Rewriter::add(RewriterVar* a, int64_t b, Location dest) { RewriterVar* Rewriter::add(RewriterVar* a, int64_t b, Location dest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = createNewVar(); RewriterVar* result = createNewVar();
addAction([=]() { this->_add(result, a, b, dest); }, { a }, ActionType::NORMAL); addAction([=]() { this->_add(result, a, b, dest); }, { a }, ActionType::NORMAL);
return result; return result;
...@@ -1229,6 +1267,8 @@ void Rewriter::_add(RewriterVar* result, RewriterVar* a, int64_t b, Location des ...@@ -1229,6 +1267,8 @@ void Rewriter::_add(RewriterVar* result, RewriterVar* a, int64_t b, Location des
} }
RewriterVar* Rewriter::allocate(int n) { RewriterVar* Rewriter::allocate(int n) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = createNewVar(); RewriterVar* result = createNewVar();
addAction([=]() { this->_allocate(result, n); }, {}, ActionType::NORMAL); addAction([=]() { this->_allocate(result, n); }, {}, ActionType::NORMAL);
return result; return result;
...@@ -1275,6 +1315,8 @@ int Rewriter::_allocate(RewriterVar* result, int n) { ...@@ -1275,6 +1315,8 @@ int Rewriter::_allocate(RewriterVar* result, int n) {
} }
RewriterVar* Rewriter::allocateAndCopy(RewriterVar* array_ptr, int n) { RewriterVar* Rewriter::allocateAndCopy(RewriterVar* array_ptr, int n) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
RewriterVar* result = createNewVar(); RewriterVar* result = createNewVar();
addAction([=]() { this->_allocateAndCopy(result, array_ptr, n); }, { array_ptr }, ActionType::NORMAL); addAction([=]() { this->_allocateAndCopy(result, array_ptr, n); }, { array_ptr }, ActionType::NORMAL);
return result; return result;
...@@ -1301,6 +1343,8 @@ void Rewriter::_allocateAndCopy(RewriterVar* result, RewriterVar* array_ptr, int ...@@ -1301,6 +1343,8 @@ void Rewriter::_allocateAndCopy(RewriterVar* result, RewriterVar* array_ptr, int
} }
RewriterVar* Rewriter::allocateAndCopyPlus1(RewriterVar* first_elem, RewriterVar* rest_ptr, int n_rest) { RewriterVar* Rewriter::allocateAndCopyPlus1(RewriterVar* first_elem, RewriterVar* rest_ptr, int n_rest) {
STAT_TIMER(t0, "us_timer_rewriter", 10);
if (n_rest > 0) if (n_rest > 0)
assert(rest_ptr != NULL); assert(rest_ptr != NULL);
else else
...@@ -1697,6 +1741,8 @@ static inline void log_ic_attempts_started(const char* debug_name) { ...@@ -1697,6 +1741,8 @@ static inline void log_ic_attempts_started(const char* debug_name) {
} }
Rewriter* Rewriter::createRewriter(void* rtn_addr, int num_args, const char* debug_name) { Rewriter* Rewriter::createRewriter(void* rtn_addr, int num_args, const char* debug_name) {
STAT_TIMER(t0, "us_timer_createrewriter", 10);
ICInfo* ic = NULL; ICInfo* ic = NULL;
// Horrible non-robust optimization: addresses below this address are probably in the binary (ex the interpreter), // Horrible non-robust optimization: addresses below this address are probably in the binary (ex the interpreter),
......
...@@ -995,7 +995,6 @@ AST_Module* parse_string(const char* code) { ...@@ -995,7 +995,6 @@ AST_Module* parse_string(const char* code) {
} }
AST_Module* parse_file(const char* fn) { AST_Module* parse_file(const char* fn) {
UNAVOIDABLE_STAT_TIMER(t0, "us_timer_cpyton_parsing");
Timer _t("parsing"); Timer _t("parsing");
if (ENABLE_PYPA_PARSER) { if (ENABLE_PYPA_PARSER) {
...@@ -1116,10 +1115,6 @@ AST_Module* caching_parse_file(const char* fn) { ...@@ -1116,10 +1115,6 @@ AST_Module* caching_parse_file(const char* fn) {
if (result == ParseResult::PYC_UNWRITABLE) if (result == ParseResult::PYC_UNWRITABLE)
return parse_file(fn); return parse_file(fn);
code = stat(cache_fn.c_str(), &cache_stat);
if (code != 0)
return parse_file(fn);
} }
static const int MAX_TRIES = 5; static const int MAX_TRIES = 5;
...@@ -1160,6 +1155,7 @@ AST_Module* caching_parse_file(const char* fn) { ...@@ -1160,6 +1155,7 @@ AST_Module* caching_parse_file(const char* fn) {
if (VERBOSITY() || tries == MAX_TRIES) { if (VERBOSITY() || tries == MAX_TRIES) {
fprintf(stderr, "Warning: corrupt or non-Pyston .pyc file found; ignoring\n"); fprintf(stderr, "Warning: corrupt or non-Pyston .pyc file found; ignoring\n");
fprintf(stderr, "%d %d %d %d\n", file_data[0], file_data[1], file_data[2], file_data[3]); fprintf(stderr, "%d %d %d %d\n", file_data[0], file_data[1], file_data[2], file_data[3]);
fprintf(stderr, "%d %d %d %d\n", getMagic()[0], getMagic()[1], getMagic()[2], getMagic()[3]);
} }
good = false; good = false;
} }
...@@ -1229,10 +1225,6 @@ AST_Module* caching_parse_file(const char* fn) { ...@@ -1229,10 +1225,6 @@ AST_Module* caching_parse_file(const char* fn) {
if (result == ParseResult::PYC_UNWRITABLE) if (result == ParseResult::PYC_UNWRITABLE)
return parse_file(fn); return parse_file(fn);
code = stat(cache_fn.c_str(), &cache_stat);
if (code != 0)
return parse_file(fn);
} }
} }
} }
......
...@@ -53,6 +53,8 @@ StatTimer* StatTimer::createStack(StatTimer& timer) { ...@@ -53,6 +53,8 @@ StatTimer* StatTimer::createStack(StatTimer& timer) {
} }
uint64_t* StatTimer::getCurrentCounter() { uint64_t* StatTimer::getCurrentCounter() {
if (counter_override)
return counter_override;
if (stack) if (stack)
return stack->_statcounter; return stack->_statcounter;
return NULL; return NULL;
......
...@@ -199,8 +199,9 @@ bool isValidGCObject(void* p) { ...@@ -199,8 +199,9 @@ bool isValidGCObject(void* p) {
} }
void setIsPythonObject(Box* b) { void setIsPythonObject(Box* b) {
auto al = global_heap.getAllocationFromInteriorPointer(b); assert(isValidGCMemory(b));
assert(al->user_data == (char*)b); auto al = GCAllocation::fromUserData(b);
if (al->kind_id == GCKind::CONSERVATIVE) { if (al->kind_id == GCKind::CONSERVATIVE) {
al->kind_id = GCKind::CONSERVATIVE_PYTHON; al->kind_id = GCKind::CONSERVATIVE_PYTHON;
} else { } else {
...@@ -268,7 +269,12 @@ void GCVisitor::visitPotentialRange(void* const* start, void* const* end) { ...@@ -268,7 +269,12 @@ void GCVisitor::visitPotentialRange(void* const* start, void* const* end) {
while (start < end) { while (start < end) {
#if TRACE_GC_MARKING #if TRACE_GC_MARKING
if (global_heap.getAllocationFromInteriorPointer(*start)) { if (global_heap.getAllocationFromInteriorPointer(*start)) {
GC_TRACE_LOG("Found conservative reference to %p from %p\n", *start, start); if (*start >= (void*)HUGE_ARENA_START)
GC_TRACE_LOG("Found conservative reference to huge object %p from %p\n", *start, start);
else if (*start >= (void*)LARGE_ARENA_START && *start < (void*)HUGE_ARENA_START)
GC_TRACE_LOG("Found conservative reference to large object %p from %p\n", *start, start);
else
GC_TRACE_LOG("Found conservative reference to %p from %p\n", *start, start);
} }
#endif #endif
...@@ -316,10 +322,16 @@ void markPhase() { ...@@ -316,10 +322,16 @@ void markPhase() {
// if (VERBOSITY()) printf("Found %d roots\n", stack.size()); // if (VERBOSITY()) printf("Found %d roots\n", stack.size());
while (void* p = stack.pop()) { while (void* p = stack.pop()) {
GC_TRACE_LOG("Looking at heap object %p\n", p);
assert(((intptr_t)p) % 8 == 0); assert(((intptr_t)p) % 8 == 0);
GCAllocation* al = GCAllocation::fromUserData(p); GCAllocation* al = GCAllocation::fromUserData(p);
#if TRACE_GC_MARKING
if (al->kind_id == GCKind::PYTHON || al->kind_id == GCKind::CONSERVATIVE_PYTHON)
GC_TRACE_LOG("Looking at %s object %p\n", static_cast<Box*>(p)->cls->tp_name, p);
else
GC_TRACE_LOG("Looking at non-python allocation %p\n", p);
#endif
assert(isMarked(al)); assert(isMarked(al));
// printf("Marking + scanning %p\n", p); // printf("Marking + scanning %p\n", p);
......
...@@ -360,6 +360,8 @@ Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) { ...@@ -360,6 +360,8 @@ Box* sorted(Box* obj, Box* cmp, Box* key, Box** args) {
} }
Box* isinstance_func(Box* obj, Box* cls) { Box* isinstance_func(Box* obj, Box* cls) {
STAT_TIMER(t0, "us_timer_isinstance_func", 10);
int rtn = PyObject_IsInstance(obj, cls); int rtn = PyObject_IsInstance(obj, cls);
if (rtn < 0) if (rtn < 0)
checkAndThrowCAPIException(); checkAndThrowCAPIException();
......
...@@ -510,7 +510,7 @@ void setupSys() { ...@@ -510,7 +510,7 @@ void setupSys() {
} }
void setupSysEnd() { void setupSysEnd() {
BoxedTuple::GCVector builtin_module_names; std::vector<Box*, StlCompatAllocator<Box*>> builtin_module_names;
for (auto& p : sys_modules_dict->d) { for (auto& p : sys_modules_dict->d) {
builtin_module_names.push_back(p.first); builtin_module_names.push_back(p.first);
} }
......
...@@ -246,6 +246,8 @@ Box* classobjStr(Box* _obj) { ...@@ -246,6 +246,8 @@ Box* classobjStr(Box* _obj) {
} }
static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing) { static Box* _instanceGetattribute(Box* _inst, Box* _attr, bool raise_on_missing) {
STAT_TIMER(t0, "us_timer_instance_getattribute", 0);
RELEASE_ASSERT(_inst->cls == instance_cls, ""); RELEASE_ASSERT(_inst->cls == instance_cls, "");
BoxedInstance* inst = static_cast<BoxedInstance*>(_inst); BoxedInstance* inst = static_cast<BoxedInstance*>(_inst);
......
...@@ -83,7 +83,7 @@ public: ...@@ -83,7 +83,7 @@ public:
if (!param_names.takes_param_names) if (!param_names.takes_param_names)
return EmptyTuple; return EmptyTuple;
BoxedTuple::GCVector elts; std::vector<Box*, StlCompatAllocator<Box*>> elts;
for (auto sr : param_names.args) for (auto sr : param_names.args)
elts.push_back(boxString(sr)); elts.push_back(boxString(sr));
if (param_names.vararg.size()) if (param_names.vararg.size())
......
...@@ -372,6 +372,8 @@ void BoxedMethodDescriptor::gcHandler(GCVisitor* v, Box* _o) { ...@@ -372,6 +372,8 @@ void BoxedMethodDescriptor::gcHandler(GCVisitor* v, Box* _o) {
} }
Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner) { Box* BoxedWrapperDescriptor::__get__(BoxedWrapperDescriptor* self, Box* inst, Box* owner) {
STAT_TIMER(t0, "us_timer_boxedwrapperdescriptor_get", 20);
RELEASE_ASSERT(self->cls == wrapperdescr_cls, ""); RELEASE_ASSERT(self->cls == wrapperdescr_cls, "");
if (inst == None) if (inst == None)
...@@ -427,7 +429,7 @@ static Box* wrapperdescrGetDoc(Box* b, void*) { ...@@ -427,7 +429,7 @@ static Box* wrapperdescrGetDoc(Box* b, void*) {
} }
Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds) { Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds) {
STAT_TIMER(t0, "us_timer_boxedwrapperobject__call__", (self->cls->is_user_defined ? 1 : 2)); STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (self->cls->is_user_defined ? 10 : 20));
assert(self->cls == wrapperobject_cls); assert(self->cls == wrapperobject_cls);
assert(args->cls == tuple_cls); assert(args->cls == tuple_cls);
...@@ -454,6 +456,8 @@ Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds ...@@ -454,6 +456,8 @@ Box* BoxedWrapperObject::__call__(BoxedWrapperObject* self, Box* args, Box* kwds
Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2, Box* BoxedWrapperObject::tppCall(Box* _self, CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Box* arg1, Box* arg2,
Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) { Box* arg3, Box** args, const std::vector<BoxedString*>* keyword_names) {
STAT_TIMER(t0, "us_timer_boxedwrapperobject_call", (_self->cls->is_user_defined ? 10 : 20));
assert(_self->cls == wrapperobject_cls); assert(_self->cls == wrapperobject_cls);
BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self); BoxedWrapperObject* self = static_cast<BoxedWrapperObject*>(_self);
......
...@@ -435,10 +435,10 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) { ...@@ -435,10 +435,10 @@ extern "C" Box* listSetitemSlice(BoxedList* self, BoxedSlice* slice, Box* v) {
if (v_as_seq == NULL) if (v_as_seq == NULL)
throwCAPIException(); throwCAPIException();
v_size = PySequence_Fast_GET_SIZE(v_as_seq); v_size = PySequence_Fast_GET_SIZE((Box*)v_as_seq);
// If lv->size is 0, lv->elts->elts is garbage // If lv->size is 0, lv->elts->elts is garbage
if (v_size) if (v_size)
v_elts = PySequence_Fast_ITEMS(v_as_seq); v_elts = PySequence_Fast_ITEMS((Box*)v_as_seq);
else else
v_elts = NULL; v_elts = NULL;
} }
......
...@@ -231,9 +231,7 @@ extern "C" void my_assert(bool b) { ...@@ -231,9 +231,7 @@ extern "C" void my_assert(bool b) {
} }
extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) { extern "C" bool isSubclass(BoxedClass* child, BoxedClass* parent) {
#if EXPENSIVE_STAT_TIMERS
STAT_TIMER(t0, "us_timer_isSubclass", 10); STAT_TIMER(t0, "us_timer_isSubclass", 10);
#endif
return PyType_IsSubtype(child, parent); return PyType_IsSubtype(child, parent);
} }
...@@ -311,7 +309,7 @@ extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) { ...@@ -311,7 +309,7 @@ extern "C" Box** unpackIntoArray(Box* obj, int64_t expected_size) {
return &l->elts->elts[0]; return &l->elts->elts[0];
} }
BoxedTuple::GCVector elts; std::vector<Box*, StlCompatAllocator<Box*>> elts;
for (auto e : obj->pyElements()) { for (auto e : obj->pyElements()) {
elts.push_back(e); elts.push_back(e);
if (elts.size() > expected_size) if (elts.size() > expected_size)
...@@ -1845,6 +1843,29 @@ extern "C" Box* getattr(Box* obj, BoxedString* attr) { ...@@ -1845,6 +1843,29 @@ extern "C" Box* getattr(Box* obj, BoxedString* attr) {
std::unique_ptr<Rewriter> rewriter( std::unique_ptr<Rewriter> rewriter(
Rewriter::createRewriter(__builtin_extract_return_addr(__builtin_return_address(0)), 2, "getattr")); Rewriter::createRewriter(__builtin_extract_return_addr(__builtin_return_address(0)), 2, "getattr"));
#if 0 && STAT_TIMERS
static uint64_t* st_id = Stats::getStatCounter("us_timer_slowpath_getattr_patchable");
static uint64_t* st_id_nopatch = Stats::getStatCounter("us_timer_slowpath_getattr_nopatch");
static uint64_t* st_id_megamorphic = Stats::getStatCounter("us_timer_slowpath_getattr_megamorphic");
ICInfo* icinfo = getICInfo(__builtin_extract_return_addr(__builtin_return_address(0)));
uint64_t* counter;
if (!icinfo)
counter = st_id_nopatch;
else if (icinfo->isMegamorphic())
counter = st_id_megamorphic;
else {
//counter = Stats::getStatCounter("us_timer_slowpath_getattr_patchable_" + std::string(obj->cls->tp_name));
//counter = Stats::getStatCounter("us_timer_slowpath_getattr_patchable_" + std::string(attr->s()));
counter = st_id;
if (!rewriter.get())
printf("");
}
if (icinfo && icinfo->start_addr == (void*)0x2aaaadb1477b)
printf("");
ScopedStatTimer st(counter, 10);
#endif
Box* val; Box* val;
if (rewriter.get()) { if (rewriter.get()) {
Location dest; Location dest;
...@@ -3947,6 +3968,8 @@ Box* nonzeroAndBox(Box* b, bool negate) { ...@@ -3947,6 +3968,8 @@ Box* nonzeroAndBox(Box* b, bool negate) {
} }
Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrite_args) { Box* compareInternal(Box* lhs, Box* rhs, int op_type, CompareRewriteArgs* rewrite_args) {
STAT_TIMER(t0, "us_timer_compareinternal", 0);
if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot) { if (op_type == AST_TYPE::Is || op_type == AST_TYPE::IsNot) {
bool neg = (op_type == AST_TYPE::IsNot); bool neg = (op_type == AST_TYPE::IsNot);
......
...@@ -329,7 +329,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept { ...@@ -329,7 +329,7 @@ extern "C" PyObject* PyString_FromFormat(const char* format, ...) noexcept {
} }
extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) { extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
assert(isSubclass(lhs->cls, str_cls)); assert(PyString_Check(lhs));
if (isSubclass(_rhs->cls, unicode_cls)) { if (isSubclass(_rhs->cls, unicode_cls)) {
Box* rtn = PyUnicode_Concat(lhs, _rhs); Box* rtn = PyUnicode_Concat(lhs, _rhs);
...@@ -337,7 +337,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) { ...@@ -337,7 +337,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
return rtn; return rtn;
} }
if (!isSubclass(_rhs->cls, str_cls)) { if (!PyString_Check(_rhs)) {
// Note: this is deliberately not returning NotImplemented, even though // Note: this is deliberately not returning NotImplemented, even though
// that would be more usual. I assume this behavior of CPython's is // that would be more usual. I assume this behavior of CPython's is
// for backwards compatibility. // for backwards compatibility.
...@@ -1140,7 +1140,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) { ...@@ -1140,7 +1140,7 @@ extern "C" Box* strMod(BoxedString* lhs, Box* rhs) {
} }
extern "C" Box* strMul(BoxedString* lhs, Box* rhs) { extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
assert(isSubclass(lhs->cls, str_cls)); assert(PyString_Check(lhs));
int n; int n;
if (isSubclass(rhs->cls, int_cls)) if (isSubclass(rhs->cls, int_cls))
...@@ -1160,7 +1160,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) { ...@@ -1160,7 +1160,7 @@ extern "C" Box* strMul(BoxedString* lhs, Box* rhs) {
} }
Box* str_richcompare(Box* lhs, Box* rhs, int op) { Box* str_richcompare(Box* lhs, Box* rhs, int op) {
assert(isSubclass(lhs->cls, str_cls)); assert(PyString_Check(lhs));
// Note: it is somehow about 50% faster to do this check inside the switch // Note: it is somehow about 50% faster to do this check inside the switch
// statement, rather than out here. It's functionally equivalent but the // statement, rather than out here. It's functionally equivalent but the
...@@ -1206,7 +1206,7 @@ Box* str_richcompare(Box* lhs, Box* rhs, int op) { ...@@ -1206,7 +1206,7 @@ Box* str_richcompare(Box* lhs, Box* rhs, int op) {
#define JUST_CENTER 2 #define JUST_CENTER 2
static Box* pad(BoxedString* self, Box* width, Box* fillchar, int justType) { static Box* pad(BoxedString* self, Box* width, Box* fillchar, int justType) {
assert(width->cls == int_cls); assert(width->cls == int_cls);
assert(isSubclass(fillchar->cls, str_cls)); assert(PyString_Check(fillchar));
assert(static_cast<BoxedString*>(fillchar)->size() == 1); assert(static_cast<BoxedString*>(fillchar)->size() == 1);
int64_t curWidth = self->size(); int64_t curWidth = self->size();
int64_t targetWidth = static_cast<BoxedInt*>(width)->n; int64_t targetWidth = static_cast<BoxedInt*>(width)->n;
...@@ -1255,13 +1255,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) { ...@@ -1255,13 +1255,13 @@ extern "C" Box* strCenter(BoxedString* lhs, Box* width, Box* fillchar) {
} }
extern "C" Box* strLen(BoxedString* self) { extern "C" Box* strLen(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
return boxInt(self->size()); return boxInt(self->size());
} }
extern "C" Box* strStr(BoxedString* self) { extern "C" Box* strStr(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
if (self->cls == str_cls) if (self->cls == str_cls)
return self; return self;
...@@ -1290,7 +1290,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla ...@@ -1290,7 +1290,7 @@ static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but cla
extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept { extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept {
BoxedString* self = (BoxedString*)obj; BoxedString* self = (BoxedString*)obj;
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
std::ostringstream os(""); std::ostringstream os("");
...@@ -1534,14 +1534,14 @@ extern "C" size_t unicodeHashUnboxed(PyUnicodeObject* self) { ...@@ -1534,14 +1534,14 @@ extern "C" size_t unicodeHashUnboxed(PyUnicodeObject* self) {
} }
extern "C" Box* strHash(BoxedString* self) { extern "C" Box* strHash(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
StringHash<char> H; StringHash<char> H;
return boxInt(H(self->data(), self->size())); return boxInt(H(self->data(), self->size()));
} }
extern "C" Box* strNonzero(BoxedString* self) { extern "C" Box* strNonzero(BoxedString* self) {
ASSERT(isSubclass(self->cls, str_cls), "%s", self->cls->tp_name); ASSERT(PyString_Check(self), "%s", self->cls->tp_name);
return boxBool(self->size() != 0); return boxBool(self->size() != 0);
} }
...@@ -1550,7 +1550,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) { ...@@ -1550,7 +1550,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
assert(isSubclass(cls, str_cls)); assert(isSubclass(cls, str_cls));
Box* rtn = str(obj); Box* rtn = str(obj);
assert(isSubclass(rtn->cls, str_cls)); assert(PyString_Check(rtn));
if (cls == str_cls) if (cls == str_cls)
return rtn; return rtn;
...@@ -1565,7 +1565,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) { ...@@ -1565,7 +1565,7 @@ extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
} }
Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) { Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef s = self->s(); llvm::StringRef s = self->s();
...@@ -1587,7 +1587,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) { ...@@ -1587,7 +1587,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
} }
Box* strIsAlpha(BoxedString* self) { Box* strIsAlpha(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
if (str.empty()) if (str.empty())
...@@ -1602,7 +1602,7 @@ Box* strIsAlpha(BoxedString* self) { ...@@ -1602,7 +1602,7 @@ Box* strIsAlpha(BoxedString* self) {
} }
Box* strIsDigit(BoxedString* self) { Box* strIsDigit(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
if (str.empty()) if (str.empty())
...@@ -1617,7 +1617,7 @@ Box* strIsDigit(BoxedString* self) { ...@@ -1617,7 +1617,7 @@ Box* strIsDigit(BoxedString* self) {
} }
Box* strIsAlnum(BoxedString* self) { Box* strIsAlnum(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
if (str.empty()) if (str.empty())
...@@ -1632,7 +1632,7 @@ Box* strIsAlnum(BoxedString* self) { ...@@ -1632,7 +1632,7 @@ Box* strIsAlnum(BoxedString* self) {
} }
Box* strIsLower(BoxedString* self) { Box* strIsLower(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
bool lowered = false; bool lowered = false;
...@@ -1654,7 +1654,7 @@ Box* strIsLower(BoxedString* self) { ...@@ -1654,7 +1654,7 @@ Box* strIsLower(BoxedString* self) {
} }
Box* strIsUpper(BoxedString* self) { Box* strIsUpper(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
...@@ -1673,7 +1673,7 @@ Box* strIsUpper(BoxedString* self) { ...@@ -1673,7 +1673,7 @@ Box* strIsUpper(BoxedString* self) {
} }
Box* strIsSpace(BoxedString* self) { Box* strIsSpace(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
if (str.empty()) if (str.empty())
...@@ -1688,7 +1688,7 @@ Box* strIsSpace(BoxedString* self) { ...@@ -1688,7 +1688,7 @@ Box* strIsSpace(BoxedString* self) {
} }
Box* strIsTitle(BoxedString* self) { Box* strIsTitle(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
llvm::StringRef str(self->s()); llvm::StringRef str(self->s());
...@@ -1723,12 +1723,12 @@ Box* strIsTitle(BoxedString* self) { ...@@ -1723,12 +1723,12 @@ Box* strIsTitle(BoxedString* self) {
} }
extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept { extern "C" PyObject* _PyString_Join(PyObject* sep, PyObject* x) noexcept {
RELEASE_ASSERT(isSubclass(sep->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(sep), "");
return string_join((PyStringObject*)sep, x); return string_join((PyStringObject*)sep, x);
} }
Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
if (!isSubclass(_self->cls, str_cls)) if (!PyString_Check(_self))
raiseExcHelper(TypeError, "descriptor 'replace' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'replace' requires a 'str' object but received a '%s'",
getTypeName(_self)); getTypeName(_self));
BoxedString* self = static_cast<BoxedString*>(_self); BoxedString* self = static_cast<BoxedString*>(_self);
...@@ -1738,11 +1738,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -1738,11 +1738,11 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
return PyUnicode_Replace((PyObject*)self, _old, _new, -1 /*count*/); return PyUnicode_Replace((PyObject*)self, _old, _new, -1 /*count*/);
#endif #endif
if (!isSubclass(_old->cls, str_cls)) if (!PyString_Check(_old))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* old = static_cast<BoxedString*>(_old); BoxedString* old = static_cast<BoxedString*>(_old);
if (!isSubclass(_new->cls, str_cls)) if (!PyString_Check(_new))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* new_ = static_cast<BoxedString*>(_new); BoxedString* new_ = static_cast<BoxedString*>(_new);
...@@ -1764,8 +1764,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) { ...@@ -1764,8 +1764,8 @@ Box* strReplace(Box* _self, Box* _old, Box* _new, Box** _args) {
} }
Box* strPartition(BoxedString* self, BoxedString* sep) { Box* strPartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(isSubclass(self->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(self), "");
RELEASE_ASSERT(isSubclass(sep->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(sep), "");
size_t found_idx = self->s().find(sep->s()); size_t found_idx = self->s().find(sep->s());
if (found_idx == std::string::npos) if (found_idx == std::string::npos)
...@@ -1779,8 +1779,8 @@ Box* strPartition(BoxedString* self, BoxedString* sep) { ...@@ -1779,8 +1779,8 @@ Box* strPartition(BoxedString* self, BoxedString* sep) {
} }
Box* strRpartition(BoxedString* self, BoxedString* sep) { Box* strRpartition(BoxedString* self, BoxedString* sep) {
RELEASE_ASSERT(isSubclass(self->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(self), "");
RELEASE_ASSERT(isSubclass(sep->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(sep), "");
size_t found_idx = self->s().rfind(sep->s()); size_t found_idx = self->s().rfind(sep->s());
if (found_idx == std::string::npos) if (found_idx == std::string::npos)
...@@ -1805,10 +1805,10 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) { ...@@ -1805,10 +1805,10 @@ Box* strFormat(BoxedString* self, BoxedTuple* args, BoxedDict* kwargs) {
} }
Box* strStrip(BoxedString* self, Box* chars) { Box* strStrip(BoxedString* self, Box* chars) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
auto str = self->s(); auto str = self->s();
if (isSubclass(chars->cls, str_cls)) { if (PyString_Check(chars)) {
auto chars_str = static_cast<BoxedString*>(chars)->s(); auto chars_str = static_cast<BoxedString*>(chars)->s();
return boxString(str.trim(chars_str)); return boxString(str.trim(chars_str));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
...@@ -1829,10 +1829,10 @@ Box* strStrip(BoxedString* self, Box* chars) { ...@@ -1829,10 +1829,10 @@ Box* strStrip(BoxedString* self, Box* chars) {
} }
Box* strLStrip(BoxedString* self, Box* chars) { Box* strLStrip(BoxedString* self, Box* chars) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
auto str = self->s(); auto str = self->s();
if (isSubclass(chars->cls, str_cls)) { if (PyString_Check(chars)) {
auto chars_str = static_cast<BoxedString*>(chars)->s(); auto chars_str = static_cast<BoxedString*>(chars)->s();
return boxString(str.ltrim(chars_str)); return boxString(str.ltrim(chars_str));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
...@@ -1853,10 +1853,10 @@ Box* strLStrip(BoxedString* self, Box* chars) { ...@@ -1853,10 +1853,10 @@ Box* strLStrip(BoxedString* self, Box* chars) {
} }
Box* strRStrip(BoxedString* self, Box* chars) { Box* strRStrip(BoxedString* self, Box* chars) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
auto str = self->s(); auto str = self->s();
if (isSubclass(chars->cls, str_cls)) { if (PyString_Check(chars)) {
auto chars_str = static_cast<BoxedString*>(chars)->s(); auto chars_str = static_cast<BoxedString*>(chars)->s();
return boxString(str.rtrim(chars_str)); return boxString(str.rtrim(chars_str));
} else if (chars->cls == none_cls) { } else if (chars->cls == none_cls) {
...@@ -1877,7 +1877,7 @@ Box* strRStrip(BoxedString* self, Box* chars) { ...@@ -1877,7 +1877,7 @@ Box* strRStrip(BoxedString* self, Box* chars) {
} }
Box* strCapitalize(BoxedString* self) { Box* strCapitalize(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
std::string s(self->s()); std::string s(self->s());
...@@ -1893,7 +1893,7 @@ Box* strCapitalize(BoxedString* self) { ...@@ -1893,7 +1893,7 @@ Box* strCapitalize(BoxedString* self) {
} }
Box* strTitle(BoxedString* self) { Box* strTitle(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
std::string s(self->s()); std::string s(self->s());
bool start_of_word = false; bool start_of_word = false;
...@@ -1917,20 +1917,20 @@ Box* strTitle(BoxedString* self) { ...@@ -1917,20 +1917,20 @@ Box* strTitle(BoxedString* self) {
} }
Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_chars) { Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_chars) {
if (!isSubclass(self->cls, str_cls)) if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'translate' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'translate' requires a 'str' object but received a '%s'",
getTypeName(self)); getTypeName(self));
std::unordered_set<char> delete_set; std::unordered_set<char> delete_set;
if (delete_chars) { if (delete_chars) {
if (!isSubclass(delete_chars->cls, str_cls)) if (!PyString_Check(delete_chars))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
delete_set.insert(delete_chars->s().begin(), delete_chars->s().end()); delete_set.insert(delete_chars->s().begin(), delete_chars->s().end());
} }
bool have_table = table != None; bool have_table = table != None;
if (have_table) { if (have_table) {
if (!isSubclass(table->cls, str_cls)) if (!PyString_Check(table))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
if (table->size() != 256) if (table->size() != 256)
raiseExcHelper(ValueError, "translation table must be 256 characters long"); raiseExcHelper(ValueError, "translation table must be 256 characters long");
...@@ -1945,7 +1945,7 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha ...@@ -1945,7 +1945,7 @@ Box* strTranslate(BoxedString* self, BoxedString* table, BoxedString* delete_cha
} }
Box* strLower(BoxedString* self) { Box* strLower(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
BoxedString* rtn = new (self->size()) BoxedString(self->s()); BoxedString* rtn = new (self->size()) BoxedString(self->s());
for (int i = 0; i < rtn->size(); i++) for (int i = 0; i < rtn->size(); i++)
...@@ -1954,7 +1954,7 @@ Box* strLower(BoxedString* self) { ...@@ -1954,7 +1954,7 @@ Box* strLower(BoxedString* self) {
} }
Box* strUpper(BoxedString* self) { Box* strUpper(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
BoxedString* rtn = new (self->size()) BoxedString(self->s()); BoxedString* rtn = new (self->size()) BoxedString(self->s());
for (int i = 0; i < rtn->size(); i++) for (int i = 0; i < rtn->size(); i++)
rtn->data()[i] = std::toupper(rtn->data()[i]); rtn->data()[i] = std::toupper(rtn->data()[i]);
...@@ -1962,7 +1962,7 @@ Box* strUpper(BoxedString* self) { ...@@ -1962,7 +1962,7 @@ Box* strUpper(BoxedString* self) {
} }
Box* strSwapcase(BoxedString* self) { Box* strSwapcase(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
BoxedString* rtn = new (self->size()) BoxedString(self->s()); BoxedString* rtn = new (self->size()) BoxedString(self->s());
for (int i = 0; i < rtn->size(); i++) { for (int i = 0; i < rtn->size(); i++) {
char c = rtn->data()[i]; char c = rtn->data()[i];
...@@ -1975,7 +1975,7 @@ Box* strSwapcase(BoxedString* self) { ...@@ -1975,7 +1975,7 @@ Box* strSwapcase(BoxedString* self) {
} }
Box* strContains(BoxedString* self, Box* elt) { Box* strContains(BoxedString* self, Box* elt) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
if (PyUnicode_Check(elt)) { if (PyUnicode_Check(elt)) {
int r = PyUnicode_Contains(self, elt); int r = PyUnicode_Contains(self, elt);
...@@ -1984,7 +1984,7 @@ Box* strContains(BoxedString* self, Box* elt) { ...@@ -1984,7 +1984,7 @@ Box* strContains(BoxedString* self, Box* elt) {
return boxBool(r); return boxBool(r);
} }
if (!isSubclass(elt->cls, str_cls)) if (!PyString_Check(elt))
raiseExcHelper(TypeError, "'in <string>' requires string as left operand, not %s", getTypeName(elt)); raiseExcHelper(TypeError, "'in <string>' requires string as left operand, not %s", getTypeName(elt));
BoxedString* sub = static_cast<BoxedString*>(elt); BoxedString* sub = static_cast<BoxedString*>(elt);
...@@ -2016,7 +2016,7 @@ extern "C" int _PyString_Eq(PyObject* o1, PyObject* o2) noexcept { ...@@ -2016,7 +2016,7 @@ extern "C" int _PyString_Eq(PyObject* o1, PyObject* o2) noexcept {
Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) { Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
Box* end = _args[0]; Box* end = _args[0];
if (!isSubclass(self->cls, str_cls)) if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'startswith' requires a 'str' object but received a '%s'",
getTypeName(self)); getTypeName(self));
...@@ -2051,7 +2051,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) { ...@@ -2051,7 +2051,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
return boxBool(r); return boxBool(r);
} }
if (!isSubclass(elt->cls, str_cls)) if (!PyString_Check(elt))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt); BoxedString* sub = static_cast<BoxedString*>(elt);
...@@ -2079,7 +2079,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) { ...@@ -2079,7 +2079,7 @@ Box* strStartswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) { Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
Box* end = _args[0]; Box* end = _args[0];
if (!isSubclass(self->cls, str_cls)) if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'", raiseExcHelper(TypeError, "descriptor 'endswith' requires a 'str' object but received a '%s'",
getTypeName(self)); getTypeName(self));
...@@ -2114,7 +2114,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) { ...@@ -2114,7 +2114,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
return False; return False;
} }
if (!isSubclass(elt->cls, str_cls)) if (!PyString_Check(elt))
raiseExcHelper(TypeError, "expected a character buffer object"); raiseExcHelper(TypeError, "expected a character buffer object");
BoxedString* sub = static_cast<BoxedString*>(elt); BoxedString* sub = static_cast<BoxedString*>(elt);
...@@ -2142,7 +2142,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) { ...@@ -2142,7 +2142,7 @@ Box* strEndswith(BoxedString* self, Box* elt, Box* start, Box** _args) {
} }
Box* strDecode(BoxedString* self, Box* encoding, Box* error) { Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
if (!isSubclass(self->cls, str_cls)) if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'decode' requires a 'str' object but received a '%s'", getTypeName(self)); raiseExcHelper(TypeError, "descriptor 'decode' requires a 'str' object but received a '%s'", getTypeName(self));
BoxedString* encoding_str = (BoxedString*)encoding; BoxedString* encoding_str = (BoxedString*)encoding;
...@@ -2151,13 +2151,13 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) { ...@@ -2151,13 +2151,13 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
if (encoding_str && encoding_str->cls == unicode_cls) if (encoding_str && encoding_str->cls == unicode_cls)
encoding_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(encoding_str, NULL); encoding_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(encoding_str, NULL);
if (encoding_str && !isSubclass(encoding_str->cls, str_cls)) if (encoding_str && !PyString_Check(encoding_str))
raiseExcHelper(TypeError, "decode() argument 1 must be string, not '%s'", getTypeName(encoding_str)); raiseExcHelper(TypeError, "decode() argument 1 must be string, not '%s'", getTypeName(encoding_str));
if (error_str && error_str->cls == unicode_cls) if (error_str && error_str->cls == unicode_cls)
error_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(error_str, NULL); error_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(error_str, NULL);
if (error_str && !isSubclass(error_str->cls, str_cls)) if (error_str && !PyString_Check(error_str))
raiseExcHelper(TypeError, "decode() argument 2 must be string, not '%s'", getTypeName(error_str)); raiseExcHelper(TypeError, "decode() argument 2 must be string, not '%s'", getTypeName(error_str));
Box* result = PyString_AsDecodedObject(self, encoding_str ? encoding_str->data() : NULL, Box* result = PyString_AsDecodedObject(self, encoding_str ? encoding_str->data() : NULL,
...@@ -2167,7 +2167,7 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) { ...@@ -2167,7 +2167,7 @@ Box* strDecode(BoxedString* self, Box* encoding, Box* error) {
} }
Box* strEncode(BoxedString* self, Box* encoding, Box* error) { Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
if (!isSubclass(self->cls, str_cls)) if (!PyString_Check(self))
raiseExcHelper(TypeError, "descriptor 'encode' requires a 'str' object but received a '%s'", getTypeName(self)); raiseExcHelper(TypeError, "descriptor 'encode' requires a 'str' object but received a '%s'", getTypeName(self));
BoxedString* encoding_str = (BoxedString*)encoding; BoxedString* encoding_str = (BoxedString*)encoding;
...@@ -2176,13 +2176,13 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) { ...@@ -2176,13 +2176,13 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
if (encoding_str && encoding_str->cls == unicode_cls) if (encoding_str && encoding_str->cls == unicode_cls)
encoding_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(encoding_str, NULL); encoding_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(encoding_str, NULL);
if (encoding_str && !isSubclass(encoding_str->cls, str_cls)) if (encoding_str && !PyString_Check(encoding_str))
raiseExcHelper(TypeError, "encode() argument 1 must be string, not '%s'", getTypeName(encoding_str)); raiseExcHelper(TypeError, "encode() argument 1 must be string, not '%s'", getTypeName(encoding_str));
if (error_str && error_str->cls == unicode_cls) if (error_str && error_str->cls == unicode_cls)
error_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(error_str, NULL); error_str = (BoxedString*)_PyUnicode_AsDefaultEncodedString(error_str, NULL);
if (error_str && !isSubclass(error_str->cls, str_cls)) if (error_str && !PyString_Check(error_str))
raiseExcHelper(TypeError, "encode() argument 2 must be string, not '%s'", getTypeName(error_str)); raiseExcHelper(TypeError, "encode() argument 2 must be string, not '%s'", getTypeName(error_str));
Box* result = PyString_AsEncodedObject(self, encoding_str ? encoding_str->data() : PyUnicode_GetDefaultEncoding(), Box* result = PyString_AsEncodedObject(self, encoding_str ? encoding_str->data() : PyUnicode_GetDefaultEncoding(),
...@@ -2192,7 +2192,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) { ...@@ -2192,7 +2192,7 @@ Box* strEncode(BoxedString* self, Box* encoding, Box* error) {
} }
extern "C" Box* strGetitem(BoxedString* self, Box* slice) { extern "C" Box* strGetitem(BoxedString* self, Box* slice) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
if (PyIndex_Check(slice)) { if (PyIndex_Check(slice)) {
Py_ssize_t n = PyNumber_AsSsize_t(slice, PyExc_IndexError); Py_ssize_t n = PyNumber_AsSsize_t(slice, PyExc_IndexError);
...@@ -2267,7 +2267,7 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) { ...@@ -2267,7 +2267,7 @@ extern "C" void strIteratorGCHandler(GCVisitor* v, Box* b) {
} }
Box* strIter(BoxedString* self) { Box* strIter(BoxedString* self) {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
return new BoxedStringIterator(self); return new BoxedStringIterator(self);
} }
...@@ -2338,7 +2338,7 @@ extern "C" char* PyString_AsString(PyObject* o) noexcept { ...@@ -2338,7 +2338,7 @@ extern "C" char* PyString_AsString(PyObject* o) noexcept {
} }
extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept { extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept {
if (isSubclass(op->cls, str_cls)) if (PyString_Check(op))
return static_cast<BoxedString*>(op)->size(); return static_cast<BoxedString*>(op)->size();
char* _s; char* _s;
...@@ -2362,7 +2362,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept { ...@@ -2362,7 +2362,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
// This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython) // This is only allowed to be called when there is only one user of the string (ie a refcount of 1 in CPython)
assert(pv); assert(pv);
assert(isSubclass((*pv)->cls, str_cls)); assert(PyString_Check(*pv));
BoxedString* s = static_cast<BoxedString*>(*pv); BoxedString* s = static_cast<BoxedString*>(*pv);
if (newsize == s->size()) if (newsize == s->size())
...@@ -2609,7 +2609,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con ...@@ -2609,7 +2609,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
RELEASE_ASSERT(index == 0, ""); RELEASE_ASSERT(index == 0, "");
// I think maybe this can just be a non-release assert? shouldn't be able to call this with // I think maybe this can just be a non-release assert? shouldn't be able to call this with
// the wrong type // the wrong type
RELEASE_ASSERT(isSubclass(self->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(self), "");
auto s = static_cast<BoxedString*>(self); auto s = static_cast<BoxedString*>(self);
*ptr = s->data(); *ptr = s->data();
...@@ -2618,7 +2618,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con ...@@ -2618,7 +2618,7 @@ static Py_ssize_t string_buffer_getreadbuf(PyObject* self, Py_ssize_t index, con
static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexcept { static Py_ssize_t string_buffer_getsegcount(PyObject* o, Py_ssize_t* lenp) noexcept {
RELEASE_ASSERT(lenp == NULL, ""); RELEASE_ASSERT(lenp == NULL, "");
RELEASE_ASSERT(isSubclass(o->cls, str_cls), ""); RELEASE_ASSERT(PyString_Check(o), "");
return 1; return 1;
} }
...@@ -2632,7 +2632,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde ...@@ -2632,7 +2632,7 @@ static Py_ssize_t string_buffer_getcharbuf(PyStringObject* self, Py_ssize_t inde
} }
static int string_buffer_getbuffer(BoxedString* self, Py_buffer* view, int flags) noexcept { static int string_buffer_getbuffer(BoxedString* self, Py_buffer* view, int flags) noexcept {
assert(isSubclass(self->cls, str_cls)); assert(PyString_Check(self));
return PyBuffer_FillInfo(view, (PyObject*)self, self->data(), self->size(), 1, flags); return PyBuffer_FillInfo(view, (PyObject*)self, self->data(), self->size(), 1, flags);
} }
......
...@@ -69,12 +69,6 @@ Box* tupleGetitemInt(BoxedTuple* self, BoxedInt* slice) { ...@@ -69,12 +69,6 @@ Box* tupleGetitemInt(BoxedTuple* self, BoxedInt* slice) {
return tupleGetitemUnboxed(self, slice->n); return tupleGetitemUnboxed(self, slice->n);
} }
extern "C" PyObject** PyTuple_Items(PyObject* op) noexcept {
RELEASE_ASSERT(PyTuple_Check(op), "");
return &static_cast<BoxedTuple*>(op)->elts[0];
}
extern "C" PyObject* PyTuple_GetItem(PyObject* op, Py_ssize_t i) noexcept { extern "C" PyObject* PyTuple_GetItem(PyObject* op, Py_ssize_t i) noexcept {
RELEASE_ASSERT(PyTuple_Check(op), ""); RELEASE_ASSERT(PyTuple_Check(op), "");
RELEASE_ASSERT(i >= 0, ""); // unlike tuple.__getitem__, PyTuple_GetItem doesn't do index wrapping RELEASE_ASSERT(i >= 0, ""); // unlike tuple.__getitem__, PyTuple_GetItem doesn't do index wrapping
......
...@@ -202,7 +202,8 @@ void* BoxVar::operator new(size_t size, BoxedClass* cls, size_t nitems) { ...@@ -202,7 +202,8 @@ void* BoxVar::operator new(size_t size, BoxedClass* cls, size_t nitems) {
ALLOC_STATS_VAR(cls); ALLOC_STATS_VAR(cls);
assert(cls); assert(cls);
ASSERT(cls->tp_basicsize >= size, "%s", cls->tp_name); // See definition of BoxedTuple for some notes on why we need this special case:
ASSERT(isSubclass(cls, tuple_cls) || cls->tp_basicsize >= size, "%s", cls->tp_name);
assert(cls->tp_itemsize > 0); assert(cls->tp_itemsize > 0);
assert(cls->tp_alloc); assert(cls->tp_alloc);
...@@ -516,6 +517,8 @@ void BoxedModule::gcHandler(GCVisitor* v, Box* b) { ...@@ -516,6 +517,8 @@ void BoxedModule::gcHandler(GCVisitor* v, Box* b) {
// TODO: should we use C++11 `noexcept' here? // TODO: should we use C++11 `noexcept' here?
extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals, extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals,
std::initializer_list<Box*> defaults) { std::initializer_list<Box*> defaults) {
STAT_TIMER(t0, "us_timer_boxclfunction", 10);
if (closure) if (closure)
assert(closure->cls == closure_cls); assert(closure->cls == closure_cls);
...@@ -2909,8 +2912,10 @@ void setupRuntime() { ...@@ -2909,8 +2912,10 @@ void setupRuntime() {
object_cls->giveAttr("__base__", None); object_cls->giveAttr("__base__", None);
// Not sure why CPython defines sizeof(PyTupleObject) to include one element,
// but we copy that, which means we have to subtract that extra pointer to get the tp_basicsize:
tuple_cls = new (0) tuple_cls = new (0)
BoxedHeapClass(object_cls, &tupleGCHandler, 0, 0, sizeof(BoxedTuple), false, boxString("tuple")); BoxedHeapClass(object_cls, &tupleGCHandler, 0, 0, sizeof(BoxedTuple) - sizeof(Box*), false, boxString("tuple"));
tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS; tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
tuple_cls->tp_itemsize = sizeof(Box*); tuple_cls->tp_itemsize = sizeof(Box*);
tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls }); tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls });
......
...@@ -554,10 +554,6 @@ public: ...@@ -554,10 +554,6 @@ public:
class BoxedTuple : public BoxVar { class BoxedTuple : public BoxVar {
public: public:
typedef std::vector<Box*, StlCompatAllocator<Box*>> GCVector;
DEFAULT_CLASS_VAR_SIMPLE(tuple_cls, sizeof(Box*));
static BoxedTuple* create(int64_t size) { return new (size) BoxedTuple(size); } static BoxedTuple* create(int64_t size) { return new (size) BoxedTuple(size); }
static BoxedTuple* create(int64_t nelts, Box** elts) { static BoxedTuple* create(int64_t nelts, Box** elts) {
BoxedTuple* rtn = new (nelts) BoxedTuple(nelts); BoxedTuple* rtn = new (nelts) BoxedTuple(nelts);
...@@ -584,14 +580,26 @@ public: ...@@ -584,14 +580,26 @@ public:
} }
static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); } static BoxedTuple* create(std::initializer_list<Box*> members) { return new (members.size()) BoxedTuple(members); }
static BoxedTuple* create(int64_t size, BoxedClass* cls) { return new (cls, size) BoxedTuple(size); } static BoxedTuple* create(int64_t size, BoxedClass* cls) {
if (cls == tuple_cls)
return new (size) BoxedTuple(size);
else
return new (cls, size) BoxedTuple(size);
}
static BoxedTuple* create(int64_t nelts, Box** elts, BoxedClass* cls) { static BoxedTuple* create(int64_t nelts, Box** elts, BoxedClass* cls) {
BoxedTuple* rtn = new (cls, nelts) BoxedTuple(nelts); BoxedTuple* rtn;
if (cls == tuple_cls)
rtn = new (nelts) BoxedTuple(nelts);
else
rtn = new (cls, nelts) BoxedTuple(nelts);
memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts); memmove(&rtn->elts[0], elts, sizeof(Box*) * nelts);
return rtn; return rtn;
} }
static BoxedTuple* create(std::initializer_list<Box*> members, BoxedClass* cls) { static BoxedTuple* create(std::initializer_list<Box*> members, BoxedClass* cls) {
return new (cls, members.size()) BoxedTuple(members); if (cls == tuple_cls)
return new (members.size()) BoxedTuple(members);
else
return new (cls, members.size()) BoxedTuple(members);
} }
static int Resize(BoxedTuple** pt, size_t newsize) noexcept; static int Resize(BoxedTuple** pt, size_t newsize) noexcept;
...@@ -602,6 +610,32 @@ public: ...@@ -602,6 +610,32 @@ public:
size_t size() const { return ob_size; } size_t size() const { return ob_size; }
// DEFAULT_CLASS_VAR_SIMPLE doesn't work because of declaring 1 element in 'elts'
void* operator new(size_t size, BoxedClass* cls, size_t nitems) __attribute__((visibility("default"))) {
ALLOC_STATS_VAR(tuple_cls)
assert(cls->tp_itemsize == sizeof(Box*));
return BoxVar::operator new(size, cls, nitems);
}
void* operator new(size_t size, size_t nitems) __attribute__((visibility("default"))) {
ALLOC_STATS_VAR(tuple_cls)
assert(tuple_cls->tp_alloc == PystonType_GenericAlloc);
assert(tuple_cls->tp_itemsize == sizeof(Box*));
assert(tuple_cls->tp_basicsize == offsetof(BoxedTuple, elts));
assert(tuple_cls->is_pyston_class);
assert(tuple_cls->attrs_offset == 0);
void* mem = gc_alloc(sizeof(BoxedTuple) + nitems * sizeof(Box*), gc::GCKind::PYTHON);
assert(mem);
BoxVar* rtn = static_cast<BoxVar*>(mem);
rtn->cls = tuple_cls;
rtn->ob_size = nitems;
return rtn;
}
private: private:
BoxedTuple(size_t size) { memset(elts, 0, sizeof(Box*) * size); } BoxedTuple(size_t size) { memset(elts, 0, sizeof(Box*) * size); }
...@@ -614,8 +648,18 @@ private: ...@@ -614,8 +648,18 @@ private:
} }
public: public:
Box* elts[0]; // CPython declares ob_item (their version of elts) to have 1 element. We want to
// copy that behavior so that the sizes of the objects match, but we want to also
// have a zero-length array in there since we have some extra compiler warnings turned
// on. _elts[1] will throw an error, but elts[1] will not.
union {
Box* elts[0];
Box* _elts[1];
};
}; };
static_assert(sizeof(BoxedTuple) == sizeof(PyTupleObject), "");
static_assert(offsetof(BoxedTuple, ob_size) == offsetof(PyTupleObject, ob_size), "");
static_assert(offsetof(BoxedTuple, elts) == offsetof(PyTupleObject, ob_item), "");
extern "C" BoxedTuple* EmptyTuple; extern "C" BoxedTuple* EmptyTuple;
extern "C" BoxedString* EmptyString; extern "C" BoxedString* EmptyString;
......
diff -ur PyICU-1.0.1_o/common.h PyICU-1.0.1/common.h
--- PyICU-1.0.1_o/common.h 2010-03-29 20:04:02.000000000 +0200
+++ PyICU-1.0.1/common.h 2015-05-18 22:38:10.625582065 +0200
@@ -199,9 +199,15 @@
#else
+// Pyston change:
+/*
#define parseArgs(args, types, rest...) \
_parseArgs(((PyTupleObject *)(args))->ob_item, \
((PyTupleObject *)(args))->ob_size, types, ##rest)
+*/
+#define parseArgs(args, types, rest...) \
+ _parseArgs(PyTuple_Items(args), PyTuple_Size(args), types, ##rest)
+
#define parseArg(arg, types, rest...) \
_parseArgs(&(arg), 1, types, ##rest)
diff -ur PyICU-1.0.1_o/_icu.cpp PyICU-1.0.1/_icu.cpp diff -ur PyICU-1.0.1_o/_icu.cpp PyICU-1.0.1/_icu.cpp
--- PyICU-1.0.1_o/_icu.cpp 2010-04-02 00:12:54.000000000 +0200 --- PyICU-1.0.1_o/_icu.cpp 2010-04-02 00:12:54.000000000 +0200
+++ PyICU-1.0.1/_icu.cpp 2015-05-19 15:26:15.131375981 +0200 +++ PyICU-1.0.1/_icu.cpp 2015-05-19 15:26:15.131375981 +0200
......
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