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
......
......@@ -94,7 +94,7 @@ bool IN_SHUTDOWN = false;
extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems) noexcept {
assert(cls);
const size_t size = _PyObject_VAR_SIZE(cls, nitems + 1);
const size_t size = _PyObject_VAR_SIZE(cls, nitems);
#ifndef NDEBUG
#if 0
......@@ -133,7 +133,7 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
Box* rtn = static_cast<Box*>(mem);
if (cls->tp_itemsize != 0)
static_cast<BoxVar*>(rtn)->ob_size = nitems + 1;
static_cast<BoxVar*>(rtn)->ob_size = nitems;
PyObject_INIT(rtn, cls);
assert(rtn->cls);
......@@ -143,7 +143,7 @@ extern "C" PyObject* PystonType_GenericAlloc(BoxedClass* cls, Py_ssize_t nitems)
extern "C" PyObject* PyType_GenericAlloc(PyTypeObject* type, Py_ssize_t nitems) noexcept {
PyObject* obj;
const size_t size = _PyObject_VAR_SIZE(type, nitems + 1);
const size_t size = _PyObject_VAR_SIZE(type, nitems);
/* note that we need to add one, for the sentinel */
if (PyType_IS_GC(type))
......@@ -2017,15 +2017,15 @@ void setupRuntime() {
PyObject_Init(object_cls, type_cls);
PyObject_Init(type_cls, type_cls);
none_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL);
none_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL);
None = new (none_cls) Box();
assert(None->cls);
gc::registerPermanentRoot(None);
// You can't actually have an instance of basestring
basestring_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL);
basestring_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(Box), false, NULL);
str_cls = new BoxedHeapClass(basestring_cls, NULL, 0, 0, sizeof(BoxedString), false, NULL);
str_cls = new (0) BoxedHeapClass(basestring_cls, NULL, 0, 0, sizeof(BoxedString), false, NULL);
str_cls->tp_flags |= Py_TPFLAGS_STRING_SUBCLASS;
str_cls->tp_itemsize = sizeof(char);
......@@ -2054,58 +2054,60 @@ void setupRuntime() {
object_cls->giveAttr("__base__", None);
tuple_cls
= new BoxedHeapClass(object_cls, &tupleGCHandler, 0, 0, sizeof(BoxedTuple), false, boxStrConstant("tuple"));
tuple_cls = new (0)
BoxedHeapClass(object_cls, &tupleGCHandler, 0, 0, sizeof(BoxedTuple), false, boxStrConstant("tuple"));
tuple_cls->tp_flags |= Py_TPFLAGS_TUPLE_SUBCLASS;
tuple_cls->tp_itemsize = sizeof(Box*);
tuple_cls->tp_mro = BoxedTuple::create({ tuple_cls, object_cls });
EmptyTuple = BoxedTuple::create({});
gc::registerPermanentRoot(EmptyTuple);
list_cls = new BoxedHeapClass(object_cls, &listGCHandler, 0, 0, sizeof(BoxedList), false, boxStrConstant("list"));
list_cls = new (0)
BoxedHeapClass(object_cls, &listGCHandler, 0, 0, sizeof(BoxedList), false, boxStrConstant("list"));
list_cls->tp_flags |= Py_TPFLAGS_LIST_SUBCLASS;
pyston_getset_cls
= new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, boxStrConstant("getset"));
attrwrapper_cls = new BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false,
static_cast<BoxedString*>(boxStrConstant("attrwrapper")));
dict_cls = new BoxedHeapClass(object_cls, &dictGCHandler, 0, 0, sizeof(BoxedDict), false,
static_cast<BoxedString*>(boxStrConstant("dict")));
pyston_getset_cls = new (0)
BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedGetsetDescriptor), false, boxStrConstant("getset"));
attrwrapper_cls = new (0) BoxedHeapClass(object_cls, &AttrWrapper::gcHandler, 0, 0, sizeof(AttrWrapper), false,
static_cast<BoxedString*>(boxStrConstant("attrwrapper")));
dict_cls = new (0) BoxedHeapClass(object_cls, &dictGCHandler, 0, 0, sizeof(BoxedDict), false,
static_cast<BoxedString*>(boxStrConstant("dict")));
dict_cls->tp_flags |= Py_TPFLAGS_DICT_SUBCLASS;
file_cls = new BoxedHeapClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist),
sizeof(BoxedFile), false, static_cast<BoxedString*>(boxStrConstant("file")));
int_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedInt), false,
static_cast<BoxedString*>(boxStrConstant("int")));
file_cls = new (0) BoxedHeapClass(object_cls, &BoxedFile::gcHandler, 0, offsetof(BoxedFile, weakreflist),
sizeof(BoxedFile), false, static_cast<BoxedString*>(boxStrConstant("file")));
int_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedInt), false,
static_cast<BoxedString*>(boxStrConstant("int")));
int_cls->tp_flags |= Py_TPFLAGS_INT_SUBCLASS;
bool_cls = new BoxedHeapClass(int_cls, NULL, 0, 0, sizeof(BoxedBool), false,
static_cast<BoxedString*>(boxStrConstant("bool")));
complex_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedComplex), false,
static_cast<BoxedString*>(boxStrConstant("complex")));
long_cls = new BoxedHeapClass(object_cls, &BoxedLong::gchandler, 0, 0, sizeof(BoxedLong), false,
static_cast<BoxedString*>(boxStrConstant("long")));
bool_cls = new (0) BoxedHeapClass(int_cls, NULL, 0, 0, sizeof(BoxedBool), false,
static_cast<BoxedString*>(boxStrConstant("bool")));
complex_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedComplex), false,
static_cast<BoxedString*>(boxStrConstant("complex")));
long_cls = new (0) BoxedHeapClass(object_cls, &BoxedLong::gchandler, 0, 0, sizeof(BoxedLong), false,
static_cast<BoxedString*>(boxStrConstant("long")));
long_cls->tp_flags |= Py_TPFLAGS_LONG_SUBCLASS;
float_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedFloat), false,
static_cast<BoxedString*>(boxStrConstant("float")));
function_cls = new BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
offsetof(BoxedFunction, in_weakreflist), sizeof(BoxedFunction), false,
static_cast<BoxedString*>(boxStrConstant("function")));
builtin_function_or_method_cls
= new BoxedHeapClass(object_cls, &functionGCHandler, 0, offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist),
sizeof(BoxedBuiltinFunctionOrMethod), false,
static_cast<BoxedString*>(boxStrConstant("builtin_function_or_method")));
float_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedFloat), false,
static_cast<BoxedString*>(boxStrConstant("float")));
function_cls = new (0) BoxedHeapClass(object_cls, &functionGCHandler, offsetof(BoxedFunction, attrs),
offsetof(BoxedFunction, in_weakreflist), sizeof(BoxedFunction), false,
static_cast<BoxedString*>(boxStrConstant("function")));
builtin_function_or_method_cls = new (0)
BoxedHeapClass(object_cls, &functionGCHandler, 0, offsetof(BoxedBuiltinFunctionOrMethod, in_weakreflist),
sizeof(BoxedBuiltinFunctionOrMethod), false,
static_cast<BoxedString*>(boxStrConstant("builtin_function_or_method")));
function_cls->simple_destructor = builtin_function_or_method_cls->simple_destructor = functionDtor;
module_cls = new BoxedHeapClass(object_cls, &moduleGCHandler, offsetof(BoxedModule, attrs), 0, sizeof(BoxedModule),
false, static_cast<BoxedString*>(boxStrConstant("module")));
member_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMemberDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("member")));
capifunc_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedCApiFunction), false,
static_cast<BoxedString*>(boxStrConstant("capifunc")));
method_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMethodDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("method")));
wrapperobject_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedWrapperObject), false,
static_cast<BoxedString*>(boxStrConstant("method-wrapper")));
wrapperdescr_cls = new BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedWrapperDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("wrapper_descriptor")));
module_cls = new (0)
BoxedHeapClass(object_cls, &moduleGCHandler, offsetof(BoxedModule, attrs), 0, sizeof(BoxedModule), false,
static_cast<BoxedString*>(boxStrConstant("module")));
member_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMemberDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("member")));
capifunc_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedCApiFunction), false,
static_cast<BoxedString*>(boxStrConstant("capifunc")));
method_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedMethodDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("method")));
wrapperobject_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedWrapperObject), false,
static_cast<BoxedString*>(boxStrConstant("method-wrapper")));
wrapperdescr_cls = new (0) BoxedHeapClass(object_cls, NULL, 0, 0, sizeof(BoxedWrapperDescriptor), false,
static_cast<BoxedString*>(boxStrConstant("wrapper_descriptor")));
EmptyString = boxStrConstant("");
gc::registerPermanentRoot(EmptyString);
......
......@@ -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