Skip to content

Commit 186122e

Browse files
committed
access dk_indices through a union
1 parent a4348cc commit 186122e

File tree

2 files changed

+18
-17
lines changed

2 files changed

+18
-17
lines changed

‎Objects/dict-common.h‎

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,12 @@ struct _dictkeysobject {
6262
- 8 bytes otherwise (Py_ssize_t*)
6363
6464
Dynamically sized, 8 is minimum. */
65-
char dk_indices[8];
65+
union {
66+
int8_t as_1[8];
67+
int16_t as_2[4];
68+
int32_t as_4[2];
69+
int64_t as_8[1];
70+
} dk_indices;
6671

6772
/* "PyDictKeyEntry dk_entries[dk_usable];" array follows:
6873
see the DK_ENTRIES() macro */

‎Objects/dictobject.c‎

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ PyDict_Fini(void)
293293
2 : sizeof(Py_ssize_t))
294294
#endif
295295
#define DK_ENTRIES(dk) \
296-
((PyDictKeyEntry*)(&(dk)->dk_indices[DK_SIZE(dk) * DK_IXSIZE(dk)]))
296+
((PyDictKeyEntry*)(&(dk)->dk_indices.as_1[DK_SIZE(dk) * DK_IXSIZE(dk)]))
297297

298298
#define DK_DEBUG_INCREF _Py_INC_REFTOTAL _Py_REF_DEBUG_COMMA
299299
#define DK_DEBUG_DECREF _Py_DEC_REFTOTAL _Py_REF_DEBUG_COMMA
@@ -312,21 +312,19 @@ dk_get_index(PyDictKeysObject *keys, Py_ssize_t i)
312312
Py_ssize_t ix;
313313

314314
if (s <= 0xff) {
315-
char *indices = (char*)keys->dk_indices;
315+
int8_t *indices = keys->dk_indices.as_1;
316316
ix = indices[i];
317317
}
318318
else if (s <= 0xffff) {
319-
int16_t *indices = (int16_t*)keys->dk_indices;
319+
int16_t *indices = keys->dk_indices.as_2;
320320
ix = indices[i];
321321
}
322-
#if SIZEOF_VOID_P > 4
323322
else if (s <= 0xffffffff) {
324-
int32_t *indices = (int32_t*)keys->dk_indices;
323+
int32_t *indices = keys->dk_indices.as_4;
325324
ix = indices[i];
326325
}
327-
#endif
328326
else {
329-
Py_ssize_t *indices = (Py_ssize_t*)keys->dk_indices;
327+
int64_t *indices = keys->dk_indices.as_8;
330328
ix = indices[i];
331329
}
332330
assert(ix >= DKIX_DUMMY);
@@ -342,24 +340,22 @@ dk_set_index(PyDictKeysObject *keys, Py_ssize_t i, Py_ssize_t ix)
342340
assert(ix >= DKIX_DUMMY);
343341

344342
if (s <= 0xff) {
345-
char *indices = (char*)keys->dk_indices;
343+
int8_t *indices = keys->dk_indices.as_1;
346344
assert(ix <= 0x7f);
347345
indices[i] = (char)ix;
348346
}
349347
else if (s <= 0xffff) {
350-
int16_t *indices = (int16_t*)keys->dk_indices;
348+
int16_t *indices = keys->dk_indices.as_2;
351349
assert(ix <= 0x7fff);
352350
indices[i] = (int16_t)ix;
353351
}
354-
#if SIZEOF_VOID_P > 4
355352
else if (s <= 0xffffffff) {
356-
int32_t *indices = (int32_t*)keys->dk_indices;
353+
int32_t *indices = keys->dk_indices.as_4;
357354
assert(ix <= 0x7fffffff);
358355
indices[i] = (int32_t)ix;
359356
}
360-
#endif
361357
else {
362-
Py_ssize_t *indices = (Py_ssize_t*)keys->dk_indices;
358+
int64_t *indices = keys->dk_indices.as_8;
363359
indices[i] = ix;
364360
}
365361
}
@@ -418,8 +414,8 @@ static PyDictKeysObject empty_keys_struct = {
418414
lookdict_split, /* dk_lookup */
419415
0, /* dk_usable (immutable) */
420416
0, /* dk_nentries */
421-
{DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
422-
DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}, /* dk_indices */
417+
.dk_indices = { .as_1 = {DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY,
418+
DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY, DKIX_EMPTY}},
423419
};
424420

425421
static PyObject *empty_values[1] = { NULL };
@@ -468,7 +464,7 @@ static PyDictKeysObject *new_keys_object(Py_ssize_t size)
468464
dk->dk_usable = usable;
469465
dk->dk_lookup = lookdict_unicode_nodummy;
470466
dk->dk_nentries = 0;
471-
memset(&dk->dk_indices[0], 0xff, es * size);
467+
memset(&dk->dk_indices.as_1[0], 0xff, es * size);
472468
memset(DK_ENTRIES(dk), 0, sizeof(PyDictKeyEntry) * usable);
473469
return dk;
474470
}

0 commit comments

Comments
 (0)