Now I changed the code, but I get a segfault.
This is the diff:
diff --git a/Objects/dictobject.c b/Objects/dictobject.c
index 6c3fc62d2e..99c48f63dc 100644
--- a/Objects/dictobject.c
+++ b/Objects/dictobject.c
@@ -1216,6 +1216,49 @@ a combined table, then the me_value slots in the old table are NULLed out.
After resizing a table is always combined,
but can be resplit by make_keys_shared().
*/
+static int
+dictresize2(PyDictObject *mp, Py_ssize_t newsize)
+{
+ Py_ssize_t numentries;
+ PyDictKeysObject *oldkeys;
+ PyDictKeyEntry *newentries;
+
+ if (newsize <= 0) {
+ PyErr_NoMemory();
+ return -1;
+ }
+ assert(IS_POWER_OF_2(newsize));
+ assert(newsize >= PyDict_MINSIZE);
+
+ oldkeys = mp->ma_keys;
+
+ /* NOTE: Current odict checks mp->ma_keys to detect resize happen.
+ * So we can't reuse oldkeys even if oldkeys->dk_size == newsize.
+ * TODO: Try reusing oldkeys when reimplement odict.
+ */
+
+ /* Allocate a new table. */
+ mp->ma_keys = new_keys_object(newsize);
+ if (mp->ma_keys == NULL) {
+ mp->ma_keys = oldkeys;
+ return -1;
+ }
+ // New table must be large enough.
+ assert(mp->ma_keys->dk_usable >= mp->ma_used);
+ if (oldkeys != NULL && oldkeys->dk_lookup == lookdict) {
+ mp->ma_keys->dk_lookup = lookdict;
+ }
+
+ numentries = mp->ma_used;
+ newentries = DK_ENTRIES(mp->ma_keys);
+
+ build_indices(mp->ma_keys, newentries, numentries);
+ mp->ma_keys->dk_usable -= numentries;
+ mp->ma_keys->dk_nentries = numentries;
+ return 0;
+}
+
+
static int
dictresize(PyDictObject *mp, Py_ssize_t newsize)
{
@@ -2382,7 +2425,6 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
{
+ mp->ma_keys->dk_nentries = numentries;
+ return 0;
+}
+
+
static int
dictresize(PyDictObject *mp, Py_ssize_t newsize)
+
+
static int
dictresize(PyDictObject *mp, Py_ssize_t newsize)
{
@@ -2382,7 +2425,6 @@ dict_update_common(PyObject *self, PyObject *args, PyObjec
t *kwds,
{
PyObject *arg = NULL;
int result = 0;
-
if (!PyArg_UnpackTuple(args, methname, 0, 1, &arg)) {
result = -1;
}
@@ -2405,8 +2447,9 @@ dict_update_common(PyObject *self, PyObject *args, PyObject *kwds,
static PyObject *
dict_update(PyObject *self, PyObject *args, PyObject *kwds)
{
- if (dict_update_common(self, args, kwds, "update") != -1)
+ if (dict_update_common(self, args, kwds, "update") != -1) {
Py_RETURN_NONE;
+ }
return NULL;
}
@@ -3419,8 +3462,34 @@ dict_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
d->ma_used = 0;
d->ma_version_tag = DICT_NEXT_VERSION();
- dictkeys_incref(Py_EMPTY_KEYS);
- d->ma_keys = Py_EMPTY_KEYS;
+
+
+ PyObject* arg = NULL;
+
+ if (args != NULL) {
+ if (! PyArg_UnpackTuple(args, __func__, 0, 1, &arg)) {
+ Py_DECREF(self);
+ return NULL;
+ }
+ }
+
+ int arg_size = ((arg != NULL)
+ ? PyObject_Length(arg)
+ : 0
+ );
+
+ int kwds_size = ((kwds != NULL)
+ ? ((PyDictObject*) kwds)->ma_used
+ : 0
+ );
+
+ Py_ssize_t keys_size = calculate_keysize(arg_size + kwds_size);
+
+ if (dictresize2((PyDictObject *)self, keys_size)) {
+ Py_DECREF(self);
+ return NULL;
+ }
+
d->ma_values = empty_values;
ASSERT_CONSISTENT(d);
return self;
if test $? -ne 0 ; then \
echo "generate-posix-vars failed" ; \
rm -f ./pybuilddir.txt ; \
exit 1 ; \
fi
Segmentation fault (core dumped)
This is the diff