Commit 267a5116 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Cache and reuse 1-length strings

CPython does this and seems like a good thing to do.  Otherwise
iterating over a string would cause lots of allocations.

One difference between this implementation and cpython's is that cpython
doesn't eagerly create them, and so it checks to see if they've been
created or not.
parent ec79d1bc
......@@ -31,6 +31,11 @@ extern "C" Box* createList() {
}
BoxedString* boxString(llvm::StringRef s) {
if (s.size() <= 1) {
if (s.size() == 0)
return EmptyString;
return characters[s.data()[0] & UCHAR_MAX];
}
return new (s.size()) BoxedString(s);
}
......
......@@ -54,6 +54,9 @@ extern "C" PyObject* string__format__(PyObject* self, PyObject* args) noexcept;
namespace pyston {
BoxedString* EmptyString;
BoxedString* characters[UCHAR_MAX + 1];
BoxedString::BoxedString(const char* s, size_t n) : interned_state(SSTATE_NOT_INTERNED) {
RELEASE_ASSERT(n != llvm::StringRef::npos, "");
if (s) {
......
......@@ -739,7 +739,6 @@ BoxedClass* object_cls, *type_cls, *none_cls, *bool_cls, *int_cls, *float_cls,
*builtin_function_or_method_cls, *attrwrapperiter_cls, *set_cls, *frozenset_cls;
BoxedTuple* EmptyTuple;
BoxedString* EmptyString;
}
extern "C" Box* createUserClass(BoxedString* name, Box* _bases, Box* _attr_dict) {
......@@ -2529,8 +2528,16 @@ void setupRuntime() {
BoxedHeapClass(object_cls, BoxedWrapperDescriptor::gcHandler, 0, 0, sizeof(BoxedWrapperDescriptor), false,
static_cast<BoxedString*>(boxString("wrapper_descriptor")));
EmptyString = boxString("");
gc::registerPermanentRoot(EmptyString);
EmptyString = new (0) BoxedString("");
// Call InternInPlace rather than InternFromString since that will
// probably try to return EmptyString
PyString_InternInPlace((Box**)&EmptyString);
for (int i = 0; i <= UCHAR_MAX; i++) {
char c = (char)i;
BoxedString* s = new (1) BoxedString(llvm::StringRef(&c, 1));
PyString_InternInPlace((Box**)&s);
characters[i] = s;
}
// Kind of hacky, but it's easier to manually construct the mro for a couple key classes
// than try to make the MRO construction code be safe against say, tuple_cls not having
......
......@@ -614,6 +614,7 @@ public:
extern "C" BoxedTuple* EmptyTuple;
extern "C" BoxedString* EmptyString;
extern BoxedString* characters[UCHAR_MAX + 1];
struct PyHasher {
size_t operator()(Box*) const;
......
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