Commit 15cf8d00 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Merge pull request #838 from kmod/perf4

make `int("some_random_string")` faster
parents 27df1a77 dba4dc72
......@@ -173,6 +173,7 @@ ExternalProject_Add(libunwind
DEPENDS libunwind_patched
UPDATE_COMMAND autoreconf -i
CONFIGURE_COMMAND ${CMAKE_SOURCE_DIR}/build_deps/libunwind/configure ${LIBUNWIND_DEBUG_CFLAGS} --prefix=${CMAKE_BINARY_DIR}/build_deps/libunwind --enable-shared=0 --disable-block-signals ${LIBUNWIND_CONSERVATIVE_CHECKS} ${LIBUNWIND_DEBUG} ${LIBUNWIND_DEBUG_FRAME}
BUILD_COMMAND make -j${TEST_THREADS}
LOG_UPDATE ON
LOG_CONFIGURE ON
LOG_BUILD ON
......
......@@ -862,6 +862,9 @@ nosearch_dbgpy_% nosearch_pydbg_%: %.py ext_pythondbg
$(call make_search,dbgpy_%)
$(call make_search,pydbg_%)
pydbg: ext_pythondbg
export PYTHON_VERSION=$$(python2.7-dbg -V 2>&1 | awk '{print $$2}'); PYTHONPATH=test/test_extension/build/lib.linux-x86_64-2.7-pydebug $(GDB) --ex "dir $(DEPS_DIR)/python-src/python2.7-$$PYTHON_VERSION/debian" $(GDB_CMDS) --args python2.7-dbg
# "kill valgrind":
kv:
ps aux | awk '/[v]algrind/ {print $$2}' | xargs kill -9; true
......
......@@ -1293,63 +1293,68 @@ static bool _needs_escaping[256]
static char _hex[17] = "0123456789abcdef"; // really only needs to be 16 but clang will complain
extern "C" PyObject* PyString_Repr(PyObject* obj, int smartquotes) noexcept {
BoxedString* self = (BoxedString*)obj;
assert(PyString_Check(self));
std::ostringstream os("");
llvm::StringRef s(self->s());
char quote = '\'';
if (smartquotes && s.find('\'', 0) != std::string::npos && s.find('\"', 0) == std::string::npos) {
quote = '\"';
BoxedString* op = (BoxedString*)obj;
size_t newsize = 2 + 4 * Py_SIZE(op);
PyObject* v;
if (newsize > PY_SSIZE_T_MAX || newsize / 4 != Py_SIZE(op)) {
PyErr_SetString(PyExc_OverflowError, "string is too large to make repr");
return NULL;
}
os << quote;
for (int i = 0; i < s.size(); i++) {
char c = s[i];
if ((c == '\'' && quote == '\"') || !_needs_escaping[c & 0xff]) {
os << c;
} else {
char special = 0;
switch (c) {
case '\t':
special = 't';
break;
case '\n':
special = 'n';
break;
case '\r':
special = 'r';
break;
case '\'':
special = '\'';
break;
case '\"':
special = '\"';
break;
case '\\':
special = '\\';
break;
}
if (special) {
os << '\\';
os << special;
} else {
os << '\\';
os << 'x';
os << _hex[(c & 0xff) / 16];
os << _hex[(c & 0xff) % 16];
}
v = PyString_FromStringAndSize((char*)NULL, newsize);
if (v == NULL) {
return NULL;
} else {
Py_ssize_t i;
char c;
char* p;
int quote;
/* figure out which quote to use; single is preferred */
quote = '\'';
if (smartquotes && memchr(op->data(), '\'', Py_SIZE(op)) && !memchr(op->data(), '"', Py_SIZE(op)))
quote = '"';
p = PyString_AS_STRING(v);
*p++ = quote;
for (i = 0; i < Py_SIZE(op); i++) {
/* There's at least enough room for a hex escape
* and a closing quote. */
assert(newsize - (p - PyString_AS_STRING(v)) >= 5);
c = op->data()[i];
if (c == quote || c == '\\')
*p++ = '\\', *p++ = c;
else if (c == '\t')
*p++ = '\\', *p++ = 't';
else if (c == '\n')
*p++ = '\\', *p++ = 'n';
else if (c == '\r')
*p++ = '\\', *p++ = 'r';
else if (c < ' ' || c >= 0x7f) {
/* For performance, we don't want to call
* PyOS_snprintf here (extra layers of
* function call). */
sprintf(p, "\\x%02x", c & 0xff);
p += 4;
} else
*p++ = c;
}
assert(newsize - (p - PyString_AS_STRING(v)) >= 1);
*p++ = quote;
*p = '\0';
if (_PyString_Resize(&v, (p - PyString_AS_STRING(v))))
return NULL;
return v;
}
os << quote;
return boxString(os.str());
}
extern "C" Box* strRepr(BoxedString* self) {
return PyString_Repr(self, 1 /* smartquotes */);
}
extern "C" Box* str_repr(Box* self) noexcept {
return PyString_Repr(self, 1 /* smartquotes */);
}
/* Unescape a backslash-escaped string. If unicode is non-zero,
the string is a u-literal. If recode_encoding is non-zero,
the string is UTF-8 encoded and should be re-encoded in the
......@@ -2882,6 +2887,7 @@ void setupStr() {
add_operators(str_cls);
str_cls->freeze();
str_cls->tp_repr = str_repr;
str_cls->tp_iter = (decltype(str_cls->tp_iter))strIter;
str_cls->tp_hash = (hashfunc)str_hash;
str_cls->tp_as_sequence->sq_length = str_length;
......
......@@ -1073,6 +1073,12 @@ static Box* typeCallInner(CallRewriteArgs* rewrite_args, ArgPassSpec argspec, Bo
made = runtimeCallInternal<S>(new_attr, &srewrite_args, new_argspec, cls, arg2, arg3, args, keyword_names);
if (!made) {
assert(S == CAPI);
if (srewrite_args.out_success && why_rewrite_allowed == NO_INIT) {
rewrite_args->out_rtn = srewrite_args.out_rtn;
rewrite_args->out_success = true;
}
return NULL;
}
......
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