Skip to content

Commit 378ebb6

Browse files
serhiy-storchakavstinner
authored andcommitted
bpo-30789: Use a single memory block for co_extra. (#2555)
* bpo-30789: Use a single memory block for co_extra. * Address review comments.
1 parent 3df9dec commit 378ebb6

File tree

1 file changed

+15
-39
lines changed

1 file changed

+15
-39
lines changed

Objects/codeobject.c

Lines changed: 15 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
/* Holder for co_extra information */
1111
typedef struct {
1212
Py_ssize_t ce_size;
13-
void **ce_extras;
13+
void *ce_extras[1];
1414
} _PyCodeObjectExtra;
1515

1616
/* all_name_chars(s): true iff all chars in s are valid NAME_CHARS */
@@ -427,7 +427,6 @@ code_dealloc(PyCodeObject *co)
427427
}
428428
}
429429

430-
PyMem_Free(co_extra->ce_extras);
431430
PyMem_Free(co_extra);
432431
}
433432

@@ -455,12 +454,13 @@ code_sizeof(PyCodeObject *co, void *unused)
455454
Py_ssize_t res = _PyObject_SIZE(Py_TYPE(co));
456455
_PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra*) co->co_extra;
457456

458-
if (co->co_cell2arg != NULL && co->co_cellvars != NULL)
457+
if (co->co_cell2arg != NULL && co->co_cellvars != NULL) {
459458
res += PyTuple_GET_SIZE(co->co_cellvars) * sizeof(Py_ssize_t);
460-
461-
if (co_extra != NULL)
462-
res += co_extra->ce_size * sizeof(co_extra->ce_extras[0]);
463-
459+
}
460+
if (co_extra != NULL) {
461+
res += sizeof(_PyCodeObjectExtra) +
462+
(co_extra->ce_size-1) * sizeof(co_extra->ce_extras[0]);
463+
}
464464
return PyLong_FromSsize_t(res);
465465
}
466466

@@ -863,48 +863,24 @@ _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
863863
PyCodeObject *o = (PyCodeObject*) code;
864864
_PyCodeObjectExtra *co_extra = (_PyCodeObjectExtra *) o->co_extra;
865865

866-
if (co_extra == NULL) {
867-
co_extra = PyMem_Malloc(sizeof(_PyCodeObjectExtra));
866+
if (co_extra == NULL || co_extra->ce_size <= index) {
867+
Py_ssize_t i = (co_extra == NULL ? 0 : co_extra->ce_size);
868+
co_extra = PyMem_Realloc(
869+
co_extra,
870+
sizeof(_PyCodeObjectExtra) +
871+
(interp->co_extra_user_count-1) * sizeof(void*));
868872
if (co_extra == NULL) {
869873
return -1;
870874
}
871-
872-
co_extra->ce_extras = PyMem_Malloc(
873-
interp->co_extra_user_count * sizeof(void*));
874-
if (co_extra->ce_extras == NULL) {
875-
PyMem_Free(co_extra);
876-
return -1;
877-
}
878-
879-
co_extra->ce_size = interp->co_extra_user_count;
880-
881-
for (Py_ssize_t i = 0; i < co_extra->ce_size; i++) {
875+
for (; i < interp->co_extra_user_count; i++) {
882876
co_extra->ce_extras[i] = NULL;
883877
}
884-
885-
o->co_extra = co_extra;
886-
}
887-
else if (co_extra->ce_size <= index) {
888-
void** ce_extras = PyMem_Realloc(
889-
co_extra->ce_extras, interp->co_extra_user_count * sizeof(void*));
890-
891-
if (ce_extras == NULL) {
892-
return -1;
893-
}
894-
895-
for (Py_ssize_t i = co_extra->ce_size;
896-
i < interp->co_extra_user_count;
897-
i++) {
898-
ce_extras[i] = NULL;
899-
}
900-
901-
co_extra->ce_extras = ce_extras;
902878
co_extra->ce_size = interp->co_extra_user_count;
879+
o->co_extra = co_extra;
903880
}
904881

905882
if (co_extra->ce_extras[index] != NULL) {
906883
freefunc free = interp->co_extra_freefuncs[index];
907-
908884
if (free != NULL) {
909885
free(co_extra->ce_extras[index]);
910886
}

0 commit comments

Comments
 (0)