Skip to content

Commit 469a42a

Browse files
committed
add _Py_c_array_t struct
1 parent bb76ef3 commit 469a42a

File tree

4 files changed

+58
-61
lines changed

4 files changed

+58
-61
lines changed

Include/internal/pycore_c_array.h

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,22 @@ extern "C" {
1010
#endif
1111

1212

13-
/* Utility for a number of growing arrays
14-
*
15-
* idx: index we need to write to
16-
* array: pointer to the array
17-
* alloc: pointer to array capacity
18-
* delta: array growth
19-
* item_size: size of each array entry
20-
*
21-
* If *array is NULL, allocate default_alloc entries.
22-
* Otherwise, double the array size if idx is out of range.
13+
/* Utility for a number of growing arrays */
14+
15+
typedef struct {
16+
void **array; /* pointer to the array */
17+
int *allocated_entries; /* pointer to the capacity of the array */
18+
size_t item_size; /* size of each element */
19+
int initial_num_entries; /* initial allocation size */
20+
} _Py_c_array_t;
21+
22+
/* If idx is out of bouds:
23+
* If arr->array is NULL, allocate arr->initial_num_entries slots.
24+
* Otherwise, double its size.
2325
*
2426
* Return 0 if successful and -1 (with exception set) otherwise.
2527
*/
26-
int _Py_EnsureArrayLargeEnough(
27-
int idx,
28-
void **array,
29-
int *alloc,
30-
int initial_size,
31-
size_t item_size);
28+
int _Py_c_array_EnsureCapacity(_Py_c_array_t *c_array, int idx);
3229

3330

3431
#ifdef __cplusplus

Python/codegen.c

Lines changed: 17 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#define NEED_OPCODE_TABLES
1919
#include "pycore_opcode_utils.h"
2020
#undef NEED_OPCODE_TABLES
21+
#include "pycore_c_array.h" // _Py_c_array_t
2122
#include "pycore_compile.h"
2223
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_NewLabel()
2324
#include "pycore_intrinsics.h"
@@ -109,40 +110,31 @@ static const int compare_masks[] = {
109110
[Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
110111
};
111112

112-
/*
113-
* Resize the array if index is out of range.
114-
*
115-
* idx: the index we want to access
116-
* arr: pointer to the array
117-
* alloc: pointer to the capacity of the array
118-
* initial_size: initial number of items
119-
* item_size: size of each item
120-
*
121-
*/
113+
122114
int
123-
_Py_EnsureArrayLargeEnough(int idx, void **array, int *alloc,
124-
int initial_size, size_t item_size)
115+
_Py_c_array_EnsureCapacity(_Py_c_array_t *c_array, int idx)
125116
{
126-
void *arr = *array;
117+
void *arr = *c_array->array;
118+
int alloc = *c_array->allocated_entries;
127119
if (arr == NULL) {
128-
int new_alloc = initial_size;
120+
int new_alloc = c_array->initial_num_entries;
129121
if (idx >= new_alloc) {
130-
new_alloc = idx + initial_size;
122+
new_alloc = idx + c_array->initial_num_entries;
131123
}
132-
arr = PyMem_Calloc(new_alloc, item_size);
124+
arr = PyMem_Calloc(new_alloc, c_array->item_size);
133125
if (arr == NULL) {
134126
PyErr_NoMemory();
135127
return ERROR;
136128
}
137-
*alloc = new_alloc;
129+
alloc = new_alloc;
138130
}
139-
else if (idx >= *alloc) {
140-
size_t oldsize = *alloc * item_size;
141-
int new_alloc = *alloc << 1;
131+
else if (idx >= alloc) {
132+
size_t oldsize = alloc * c_array->item_size;
133+
int new_alloc = alloc << 1;
142134
if (idx >= new_alloc) {
143-
new_alloc = idx + initial_size;
135+
new_alloc = idx + c_array->initial_num_entries;
144136
}
145-
size_t newsize = new_alloc * item_size;
137+
size_t newsize = new_alloc * c_array->item_size;
146138

147139
if (oldsize > (SIZE_MAX >> 1)) {
148140
PyErr_NoMemory();
@@ -155,12 +147,13 @@ _Py_EnsureArrayLargeEnough(int idx, void **array, int *alloc,
155147
PyErr_NoMemory();
156148
return ERROR;
157149
}
158-
*alloc = new_alloc;
150+
alloc = new_alloc;
159151
arr = tmp;
160152
memset((char *)arr + oldsize, 0, newsize - oldsize);
161153
}
162154

163-
*array = arr;
155+
*c_array->array = arr;
156+
*c_array->allocated_entries = alloc;
164157
return SUCCESS;
165158
}
166159

Python/flowgraph.c

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#include "Python.h"
22
#include "opcode.h"
3-
#include "pycore_c_array.h" // _Py_EnsureArrayLargeEnough
3+
#include "pycore_c_array.h" // _Py_c_array_EnsureCapacity
44
#include "pycore_flowgraph.h"
55
#include "pycore_compile.h"
66
#include "pycore_intrinsics.h"
@@ -142,13 +142,14 @@ static int
142142
basicblock_next_instr(basicblock *b)
143143
{
144144
assert(b != NULL);
145-
RETURN_IF_ERROR(
146-
_Py_EnsureArrayLargeEnough(
147-
b->b_iused + 1,
148-
(void**)&b->b_instr,
149-
&b->b_ialloc,
150-
DEFAULT_BLOCK_SIZE,
151-
sizeof(cfg_instr)));
145+
_Py_c_array_t array = {
146+
.array = (void**)&b->b_instr,
147+
.allocated_entries = &b->b_ialloc,
148+
.item_size = sizeof(cfg_instr),
149+
.initial_num_entries = DEFAULT_BLOCK_SIZE,
150+
};
151+
152+
RETURN_IF_ERROR(_Py_c_array_EnsureCapacity(&array, b->b_iused + 1));
152153
return b->b_iused++;
153154
}
154155

Python/instruction_sequence.c

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
#include "Python.h"
99

10-
#include "pycore_c_array.h" // _Py_EnsureArrayLargeEnough
10+
#include "pycore_c_array.h" // _Py_c_array_EnsureCapacity
1111
#include "pycore_compile.h" // _PyInstruction
1212
#include "pycore_opcode_utils.h"
1313
#include "pycore_opcode_metadata.h" // OPCODE_HAS_ARG, etc
@@ -37,12 +37,16 @@ static int
3737
instr_sequence_next_inst(instr_sequence *seq) {
3838
assert(seq->s_instrs != NULL || seq->s_used == 0);
3939

40-
RETURN_IF_ERROR(
41-
_Py_EnsureArrayLargeEnough(seq->s_used + 1,
42-
(void**)&seq->s_instrs,
43-
&seq->s_allocated,
44-
INITIAL_INSTR_SEQUENCE_SIZE,
45-
sizeof(instruction)));
40+
41+
_Py_c_array_t array = {
42+
.array = (void**)&seq->s_instrs,
43+
.allocated_entries = &seq->s_allocated,
44+
.item_size = sizeof(instruction),
45+
.initial_num_entries = INITIAL_INSTR_SEQUENCE_SIZE,
46+
};
47+
48+
RETURN_IF_ERROR(_Py_c_array_EnsureCapacity(&array, seq->s_used + 1));
49+
4650
assert(seq->s_allocated >= 0);
4751
assert(seq->s_used < seq->s_allocated);
4852
return seq->s_used++;
@@ -59,12 +63,14 @@ int
5963
_PyInstructionSequence_UseLabel(instr_sequence *seq, int lbl)
6064
{
6165
int old_size = seq->s_labelmap_size;
62-
RETURN_IF_ERROR(
63-
_Py_EnsureArrayLargeEnough(lbl,
64-
(void**)&seq->s_labelmap,
65-
&seq->s_labelmap_size,
66-
INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
67-
sizeof(int)));
66+
_Py_c_array_t array = {
67+
.array = (void**)&seq->s_labelmap,
68+
.allocated_entries = &seq->s_labelmap_size,
69+
.item_size = sizeof(int),
70+
.initial_num_entries = INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
71+
};
72+
73+
RETURN_IF_ERROR(_Py_c_array_EnsureCapacity(&array, lbl));
6874

6975
for(int i = old_size; i < seq->s_labelmap_size; i++) {
7076
seq->s_labelmap[i] = -111; /* something weird, for debugging */

0 commit comments

Comments
 (0)