Show More
@@ -19,6 +19,9 | |||||
19 | * |
|
19 | * | |
20 | * We modify Python integers for refcounting, but those integers are |
|
20 | * We modify Python integers for refcounting, but those integers are | |
21 | * never visible to Python code. |
|
21 | * never visible to Python code. | |
|
22 | * | |||
|
23 | * We mutate strings in-place, but leave them immutable once they can | |||
|
24 | * be seen by Python code. | |||
22 | */ |
|
25 | */ | |
23 | typedef struct { |
|
26 | typedef struct { | |
24 | PyObject_HEAD |
|
27 | PyObject_HEAD | |
@@ -40,6 +43,7 static inline Py_ssize_t _finddir(PyObje | |||||
40 |
|
43 | |||
41 | static int _addpath(PyObject *dirs, PyObject *path) |
|
44 | static int _addpath(PyObject *dirs, PyObject *path) | |
42 | { |
|
45 | { | |
|
46 | const char *cpath = PyString_AS_STRING(path); | |||
43 | Py_ssize_t pos = PyString_GET_SIZE(path); |
|
47 | Py_ssize_t pos = PyString_GET_SIZE(path); | |
44 | PyObject *key = NULL; |
|
48 | PyObject *key = NULL; | |
45 | int ret = -1; |
|
49 | int ret = -1; | |
@@ -47,15 +51,24 static int _addpath(PyObject *dirs, PyOb | |||||
47 | while ((pos = _finddir(path, pos - 1)) != -1) { |
|
51 | while ((pos = _finddir(path, pos - 1)) != -1) { | |
48 | PyObject *val; |
|
52 | PyObject *val; | |
49 |
|
53 | |||
50 | key = PyString_FromStringAndSize(PyString_AS_STRING(path), pos); |
|
54 | /* It's likely that every prefix already has an entry | |
51 |
|
55 | in our dict. Try to avoid allocating and | ||
|
56 | deallocating a string for each prefix we check. */ | |||
|
57 | if (key != NULL) | |||
|
58 | ((PyStringObject *)key)->ob_shash = -1; | |||
|
59 | else { | |||
|
60 | /* Force Python to not reuse a small shared string. */ | |||
|
61 | key = PyString_FromStringAndSize(cpath, | |||
|
62 | pos < 2 ? 2 : pos); | |||
52 | if (key == NULL) |
|
63 | if (key == NULL) | |
53 | goto bail; |
|
64 | goto bail; | |
|
65 | } | |||
|
66 | PyString_GET_SIZE(key) = pos; | |||
|
67 | PyString_AS_STRING(key)[pos] = '\0'; | |||
54 |
|
68 | |||
55 | val = PyDict_GetItem(dirs, key); |
|
69 | val = PyDict_GetItem(dirs, key); | |
56 | if (val != NULL) { |
|
70 | if (val != NULL) { | |
57 | PyInt_AS_LONG(val) += 1; |
|
71 | PyInt_AS_LONG(val) += 1; | |
58 | Py_CLEAR(key); |
|
|||
59 | continue; |
|
72 | continue; | |
60 | } |
|
73 | } | |
61 |
|
74 |
General Comments 0
You need to be logged in to leave comments.
Login now