Commit ba389a2e authored by Kevin Modzelewski's avatar Kevin Modzelewski

Reduce unnecessary string memsets

Particularly for string slicing, where we would
always memset the string data to zero, and then
immediately memcpy it.
parent b44f8a5b
......@@ -57,13 +57,10 @@ BoxedString* EmptyString;
BoxedString* characters[UCHAR_MAX + 1];
BoxedString::BoxedString(const char* s, size_t n) : interned_state(SSTATE_NOT_INTERNED) {
assert(s);
RELEASE_ASSERT(n != llvm::StringRef::npos, "");
if (s) {
memmove(data(), s, n);
data()[n] = 0;
} else {
memset(data(), 0, n + 1);
}
memmove(data(), s, n);
data()[n] = 0;
}
BoxedString::BoxedString(llvm::StringRef lhs, llvm::StringRef rhs) : interned_state(SSTATE_NOT_INTERNED) {
......@@ -85,6 +82,13 @@ BoxedString::BoxedString(size_t n, char c) : interned_state(SSTATE_NOT_INTERNED)
data()[n] = 0;
}
BoxedString::BoxedString(size_t n) : interned_state(SSTATE_NOT_INTERNED) {
RELEASE_ASSERT(n != llvm::StringRef::npos, "");
// Note: no memset. add the null-terminator for good measure though
// (CPython does the same thing).
data()[n] = 0;
}
extern "C" char PyString_GetItem(PyObject* op, ssize_t n) noexcept {
RELEASE_ASSERT(PyString_Check(op), "");
return static_cast<const BoxedString*>(op)->s()[n];
......@@ -1577,11 +1581,12 @@ Box* _strSlice(BoxedString* self, i64 start, i64 stop, i64 step, i64 length) {
assert(start < s.size());
assert(-1 <= stop);
}
assert(length >= 0);
if (length == 0)
return EmptyString;
BoxedString* bs = new (length) BoxedString(nullptr, length);
BoxedString* bs = BoxedString::createUninitializedString(length);
copySlice(bs->data(), s.data(), start, step, length);
return bs;
}
......@@ -2307,17 +2312,9 @@ extern "C" int PyString_AsStringAndSize(register PyObject* obj, register char**
return 0;
}
BoxedString* createUninitializedString(ssize_t n) {
return new (n) BoxedString(n, 0);
}
char* getWriteableStringContents(BoxedString* s) {
return s->data();
}
extern "C" PyObject* PyString_FromStringAndSize(const char* s, ssize_t n) noexcept {
if (s == NULL)
return createUninitializedString(n);
return BoxedString::createUninitializedString(n);
return boxString(llvm::StringRef(s, n));
}
......@@ -2334,7 +2331,7 @@ extern "C" char* PyString_AsString(PyObject* o) noexcept {
return string_getbuffer(o);
BoxedString* s = static_cast<BoxedString*>(o);
return getWriteableStringContents(s);
return s->getWriteableStringContents();
}
extern "C" Py_ssize_t PyString_Size(PyObject* op) noexcept {
......
......@@ -120,13 +120,6 @@ BoxedString* boxStringTwine(const llvm::Twine& s);
extern "C" Box* decodeUTF8StringPtr(llvm::StringRef s);
// creates an uninitialized string of length n; useful for directly constructing into the string and avoiding copies:
BoxedString* createUninitializedString(ssize_t n);
// Gets a writeable pointer to the contents of a string.
// Is only meant to be used with something just created from createUninitializedString(), though
// in theory it might work in more cases.
char* getWriteableStringContents(BoxedString* s);
extern "C" inline void listAppendInternal(Box* self, Box* v) __attribute__((visibility("default")));
extern "C" void listAppendArrayInternal(Box* self, Box** v, int nelts);
extern "C" Box* boxCLFunction(CLFunction* f, BoxedClosure* closure, Box* globals,
......@@ -480,9 +473,20 @@ public:
explicit BoxedString(llvm::StringRef s) __attribute__((visibility("default")));
explicit BoxedString(llvm::StringRef lhs, llvm::StringRef rhs) __attribute__((visibility("default")));
// creates an uninitialized string of length n; useful for directly constructing into the string and avoiding
// copies:
static BoxedString* createUninitializedString(ssize_t n) { return new (n) BoxedString(n); }
// Gets a writeable pointer to the contents of a string.
// Is only meant to be used with something just created from createUninitializedString(), though
// in theory it might work in more cases.
char* getWriteableStringContents() { return s_data; }
private:
void* operator new(size_t size) = delete;
BoxedString(size_t n); // non-initializing constructor
char s_data[0];
friend void setupRuntime();
......
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