Commit 6469984e authored by Travis Hance's avatar Travis Hance

Create macros DEFAULT_CLASS_VAR and DEFAULT_CLASS_VAR_SIMPLE, analagous to...

Create macros DEFAULT_CLASS_VAR and DEFAULT_CLASS_VAR_SIMPLE, analagous to DEFAULT_CLASS and DEFAULT_CLASS_SIMPLE, which declare the `operator new`. Also, get rid of the seemingly useless +1s for sizes.
parent c8bb686f
......@@ -484,17 +484,14 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
#define DEFAULT_CLASS(default_cls) \
void* operator new(size_t size, BoxedClass * cls) __attribute__((visibility("default"))) { \
assert(cls->tp_itemsize == 0); \
return Box::operator new(size, cls, 0); \
} \
void* operator new(size_t size) __attribute__((visibility("default"))) { \
assert(default_cls->tp_itemsize == 0); \
return Box::operator new(size, default_cls, 0); \
}
#define ALLOCATABLE_WITH_ITEMS \
void* operator new(size_t size, BoxedClass * cls, size_t nitems) __attribute__((visibility("default"))) { \
return Box::operator new(size, cls, nitems); \
}
// The restrictions on when you can use the SIMPLE (ie fast) variant are encoded as
// asserts in the 1-arg operator new function:
#define DEFAULT_CLASS_SIMPLE(default_cls) \
......@@ -525,6 +522,48 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
/* TODO: there should be a way to not have to do this nested inlining by hand */ \
}
#define DEFAULT_CLASS_VAR(default_cls, itemsize) \
static_assert(itemsize > 0, ""); \
/* asserts that the class in question is a subclass of BoxVar */ \
inline void _base_check() { \
static_assert(std::is_base_of<BoxVar, std::remove_pointer<decltype(this)>::type>::value, ""); \
} \
\
void* operator new(size_t size, BoxedClass * cls, size_t nitems) __attribute__((visibility("default"))) { \
assert(cls->tp_itemsize == itemsize); \
return Box::operator new(size, cls, nitems); \
} \
void* operator new(size_t size, size_t nitems) __attribute__((visibility("default"))) { \
assert(default_cls->tp_itemsize == itemsize); \
return Box::operator new(size, default_cls, nitems); \
}
#define DEFAULT_CLASS_VAR_SIMPLE(default_cls, itemsize) \
static_assert(itemsize > 0, ""); \
inline void _base_check() { \
static_assert(std::is_base_of<BoxVar, std::remove_pointer<decltype(this)>::type>::value, ""); \
} \
\
void* operator new(size_t size, BoxedClass * cls, size_t nitems) __attribute__((visibility("default"))) { \
assert(cls->tp_itemsize == itemsize); \
return Box::operator new(size, cls, nitems); \
} \
void* operator new(size_t size, size_t nitems) __attribute__((visibility("default"))) { \
assert(default_cls->tp_alloc == PystonType_GenericAlloc); \
assert(default_cls->tp_itemsize == itemsize); \
assert(default_cls->tp_basicsize == size); \
assert(default_cls->is_pyston_class); \
assert(default_cls->attrs_offset == 0); \
\
void* mem = gc_alloc(size + nitems * itemsize, gc::GCKind::PYTHON); \
assert(mem); \
\
BoxVar* rtn = static_cast<BoxVar*>(mem); \
rtn->cls = default_cls; \
rtn->ob_size = nitems; \
return rtn; \
}
// CPython C API compatibility class:
class BoxVar : public Box {
public:
......
......@@ -461,8 +461,8 @@ void setupSys() {
sys_module->giveAttr("maxint", boxInt(PYSTON_INT_MAX));
sys_module->giveAttr("maxsize", boxInt(PY_SSIZE_T_MAX));
sys_flags_cls = new BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false,
static_cast<BoxedString*>(boxString("flags")));
sys_flags_cls = new (0) BoxedHeapClass(object_cls, BoxedSysFlags::gcHandler, 0, 0, sizeof(BoxedSysFlags), false,
static_cast<BoxedString*>(boxString("flags")));
sys_flags_cls->giveAttr("__new__",
new BoxedFunction(boxRTFunction((void*)BoxedSysFlags::__new__, UNKNOWN, 1, 0, true, true)));
#define ADD(name) \
......
......@@ -32,14 +32,14 @@ extern "C" Box* createList() {
BoxedString* _boxStrConstant(const char* chars) {
size_t len = strlen(chars);
return new (len) BoxedString(chars, len);
return new (len + 1) BoxedString(chars, len);
}
extern "C" BoxedString* boxStrConstant(const char* chars) {
return _boxStrConstant(chars);
}
BoxedString* _boxStrConstantSize(const char* chars, size_t n) {
return new (n) BoxedString(chars, n);
return new (n + 1) BoxedString(chars, n);
}
extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) {
......@@ -47,18 +47,18 @@ extern "C" BoxedString* boxStrConstantSize(const char* chars, size_t n) {
}
extern "C" Box* boxStringPtr(const std::string* s) {
return new (s->size()) BoxedString(s->c_str(), s->size());
return new (s->size() + 1) BoxedString(s->c_str(), s->size());
}
Box* boxStringRef(llvm::StringRef s) {
return new (s.size()) BoxedString(s);
return new (s.size() + 1) BoxedString(s);
}
Box* boxString(const std::string& s) {
return new (s.size()) BoxedString(s.c_str(), s.size());
return new (s.size() + 1) BoxedString(s.c_str(), s.size());
}
Box* boxString(std::string&& s) {
return new (s.size()) BoxedString(s.c_str(), s.size());
return new (s.size() + 1) BoxedString(s.c_str(), s.size());
}
Box* boxStringTwine(const llvm::Twine& t) {
......
......@@ -341,7 +341,7 @@ extern "C" Box* strAdd(BoxedString* lhs, Box* _rhs) {
}
BoxedString* rhs = static_cast<BoxedString*>(_rhs);
return new (lhs->size() + rhs->size()) BoxedString(lhs->s, rhs->s);
return new (lhs->size() + rhs->size() + 1) BoxedString(lhs->s, rhs->s);
}
static llvm::StringMap<Box*> interned_strings;
......@@ -1547,7 +1547,7 @@ extern "C" Box* strNew(BoxedClass* cls, Box* obj) {
BoxedString* _rtn = static_cast<BoxedString*>(rtn);
return new (cls, _rtn->size()) BoxedString(_rtn->s);
return new (cls, _rtn->size() + 1) BoxedString(_rtn->s);
}
extern "C" Box* basestringNew(BoxedClass* cls, Box* args, Box* kwargs) {
......@@ -1571,7 +1571,7 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
if (length == 0)
return EmptyString;
BoxedString* bs = new (length) BoxedString(nullptr, length);
BoxedString* bs = new (length + 1) BoxedString(nullptr, length);
copySlice(bs->data(), s.data(), start, step, length);
return bs;
}
......@@ -2289,7 +2289,7 @@ extern "C" int PyString_AsStringAndSize(register PyObject* obj, register char**
BoxedString* createUninitializedString(ssize_t n) {
// I *think* this should avoid doing any copies, by using move constructors:
return new (n) BoxedString(n, 0);
return new (n + 1) BoxedString(n, 0);
}
char* getWriteableStringContents(BoxedString* s) {
......@@ -2340,7 +2340,7 @@ extern "C" int _PyString_Resize(PyObject** pv, Py_ssize_t newsize) noexcept {
BoxedString* resized;
if (s->cls == str_cls)
resized = new (newsize) BoxedString(newsize, 0); // we need an uninitialized string, but this will memset
resized = new (newsize + 1) BoxedString(newsize, 0); // we need an uninitialized string, but this will memset
else
resized = new (s->cls, newsize)
BoxedString(newsize, 0); // we need an uninitialized string, but this will memset
......
This diff is collapsed.
......@@ -258,8 +258,7 @@ private:
friend void setupRuntime();
friend void setupSys();
DEFAULT_CLASS(type_cls);
ALLOCATABLE_WITH_ITEMS;
DEFAULT_CLASS_VAR(type_cls, sizeof(SlotOffset));
};
static_assert(sizeof(pyston::Box) == sizeof(struct _object), "");
......@@ -417,19 +416,7 @@ public:
char* data() { return const_cast<char*>(s.data()); }
size_t size() { return s.size(); }
void* operator new(size_t size, size_t ssize) __attribute__((visibility("default"))) {
BoxVar* rtn = static_cast<BoxVar*>(gc_alloc(str_cls->tp_basicsize + ssize + 1, gc::GCKind::PYTHON));
// TODO need to initialize ob_size for other objects as well
rtn->ob_size = ssize + 1;
rtn->cls = str_cls;
return rtn;
}
void* operator new(size_t size, BoxedClass* cls, size_t ssize) __attribute__((visibility("default"))) {
BoxVar* rtn = static_cast<BoxVar*>(cls->tp_alloc(cls, ssize + 1));
rtn->cls = cls;
return rtn;
}
DEFAULT_CLASS_VAR_SIMPLE(str_cls, sizeof(char));
// these should be private, but strNew needs them
BoxedString(const char* s, size_t n) __attribute__((visibility("default")));
......@@ -530,18 +517,7 @@ public:
Box** elts;
void* operator new(size_t size, size_t nelts) __attribute__((visibility("default"))) {
BoxVar* rtn = static_cast<BoxVar*>(gc_alloc(_PyObject_VAR_SIZE(tuple_cls, nelts + 1), gc::GCKind::PYTHON));
rtn->ob_size = nelts;
rtn->cls = tuple_cls;
return rtn;
}
void* operator new(size_t size, BoxedClass* cls, size_t nelts) __attribute__((visibility("default"))) {
BoxVar* rtn = static_cast<BoxVar*>(cls->tp_alloc(cls, nelts));
rtn->cls = cls;
return rtn;
}
DEFAULT_CLASS_VAR_SIMPLE(tuple_cls, sizeof(Box*));
static BoxedTuple* create(int64_t size) { return new (size) BoxedTuple(size); }
static BoxedTuple* create(int64_t nelts, Box** elts) {
......
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