Skip to content

Commit 21c1679

Browse files
committed
wip: code cleanup, renames, comments
1 parent 2e025b0 commit 21c1679

File tree

1 file changed

+79
-87
lines changed

1 file changed

+79
-87
lines changed

Objects/obmalloc.c

Lines changed: 79 additions & 87 deletions
Original file line numberDiff line numberDiff line change
@@ -909,6 +909,7 @@ static int running_on_valgrind = -1;
909909
*/
910910
#define ARENA_BITS 18
911911
#define ARENA_SIZE (1 << ARENA_BITS) /* 256 KiB */
912+
#define ARENA_SIZE_MASK (ARENA_SIZE - 1)
912913

913914
#ifdef WITH_MEMORY_LIMITS
914915
#define MAX_ARENAS (SMALL_MEMORY_LIMIT / ARENA_SIZE)
@@ -1235,18 +1236,21 @@ _Py_GetAllocatedBlocks(void)
12351236
}
12361237

12371238
/*==========================================================================*/
1238-
/* radix tree for tracking arena coverage
1239+
/* radix tree for tracking arena usage
12391240
1240-
key format (2^20 arena size)
1241-
15 -> MAP1
1242-
15 -> MAP2
1243-
14 -> MAP3
1241+
bit allocation for keys (2^20 arena size)
1242+
1243+
64-bit pointers:
1244+
16 -> ignored (BITS - PHYSICAL_BITS)
1245+
10 -> MAP_TOP
1246+
10 -> MAP_MID
1247+
8 -> MAP_BOT
12441248
20 -> ideal aligned arena
12451249
----
12461250
64
12471251
1248-
key format (2^20 arena size)
1249-
12 -> MAP3
1252+
32-bit pointers:
1253+
12 -> MAP_BOT
12501254
20 -> ideal aligned arena
12511255
----
12521256
32
@@ -1264,11 +1268,9 @@ _Py_GetAllocatedBlocks(void)
12641268
*/
12651269
#define PHYSICAL_BITS 48
12661270

1267-
/* need more layers of radix tree */
1271+
/* use the top and mid layers of the radix tree */
12681272
#define USE_INTERIOR_NODES
12691273

1270-
#define arena_root_t arena_map1_t
1271-
12721274
#elif SIZEOF_VOID_P == 4
12731275

12741276
#define BITS 32
@@ -1281,130 +1283,123 @@ _Py_GetAllocatedBlocks(void)
12811283

12821284
#endif /* SIZEOF_VOID_P */
12831285

1284-
#define ARENA_MASK (ARENA_SIZE - 1)
1285-
12861286
/* arena_coverage_t members require this to be true */
12871287
#if ARENA_BITS >= 32
12881288
# error "arena size must be < 2^32"
12891289
#endif
12901290

12911291
#ifdef USE_INTERIOR_NODES
1292-
/* bits used for MAP1 and MAP2 nodes */
1292+
/* number of bits used for MAP_TOP and MAP_MID nodes */
12931293
#define INTERIOR_BITS ((PHYSICAL_BITS - ARENA_BITS + 2) / 3)
12941294
#else
12951295
#define INTERIOR_BITS 0
12961296
#endif
12971297

1298-
#define MAP1_BITS INTERIOR_BITS
1299-
#define MAP1_LENGTH (1 << MAP1_BITS)
1300-
#define MAP1_MASK (MAP3_LENGTH - 1)
1298+
#define MAP_TOP_BITS INTERIOR_BITS
1299+
#define MAP_TOP_LENGTH (1 << MAP_TOP_BITS)
1300+
#define MAP_TOP_MASK (MAP_BOT_LENGTH - 1)
13011301

1302-
#define MAP2_BITS INTERIOR_BITS
1303-
#define MAP2_LENGTH (1 << MAP2_BITS)
1304-
#define MAP2_MASK (MAP2_LENGTH - 1)
1302+
#define MAP_MID_BITS INTERIOR_BITS
1303+
#define MAP_MID_LENGTH (1 << MAP_MID_BITS)
1304+
#define MAP_MID_MASK (MAP_MID_LENGTH - 1)
13051305

1306-
#define MAP3_BITS (PHYSICAL_BITS - ARENA_BITS - 2*INTERIOR_BITS)
1307-
#define MAP3_LENGTH (1 << MAP3_BITS)
1308-
#define MAP3_MASK (MAP3_LENGTH - 1)
1306+
#define MAP_BOT_BITS (PHYSICAL_BITS - ARENA_BITS - 2*INTERIOR_BITS)
1307+
#define MAP_BOT_LENGTH (1 << MAP_BOT_BITS)
1308+
#define MAP_BOT_MASK (MAP_BOT_LENGTH - 1)
13091309

1310-
#define MAP3_SHIFT ARENA_BITS
1311-
#define MAP2_SHIFT (MAP3_BITS + MAP3_SHIFT)
1312-
#define MAP1_SHIFT (MAP2_BITS + MAP2_SHIFT)
1310+
#define MAP_BOT_SHIFT ARENA_BITS
1311+
#define MAP_MID_SHIFT (MAP_BOT_BITS + MAP_BOT_SHIFT)
1312+
#define MAP_TOP_SHIFT (MAP_MID_BITS + MAP_MID_SHIFT)
13131313

13141314
#define AS_UINT(p) ((uintptr_t)(p))
1315-
#define MAP3_INDEX(p) ((AS_UINT(p) >> MAP3_SHIFT) & MAP3_MASK)
1316-
#define MAP2_INDEX(p) ((AS_UINT(p) >> MAP2_SHIFT) & MAP2_MASK)
1317-
#define MAP1_INDEX(p) ((AS_UINT(p) >> MAP1_SHIFT) & MAP1_MASK)
1315+
#define MAP_BOT_INDEX(p) ((AS_UINT(p) >> MAP_BOT_SHIFT) & MAP_BOT_MASK)
1316+
#define MAP_MID_INDEX(p) ((AS_UINT(p) >> MAP_MID_SHIFT) & MAP_MID_MASK)
1317+
#define MAP_TOP_INDEX(p) ((AS_UINT(p) >> MAP_TOP_SHIFT) & MAP_TOP_MASK)
13181318

13191319
#if PHYSICAL_BITS > BITS
1320+
/* Return non-physical bits of pointer. Should be same for all valid
1321+
* pointers if PHYSICAL_BITS set correctly. */
13201322
#define HIGH_BITS(p) (AS_UINT(p) >> PHYSICAL_BITS)
13211323
#else
13221324
#define HIGH_BITS(p) 0
13231325
#endif
13241326

13251327

1326-
/* See arena_map_mark_used() for the meaning of these members. */
1328+
/* This is the leaf of the radix tree. See arena_map_mark_used() for the
1329+
* meaning of these members. */
13271330
typedef struct {
13281331
int32_t tail_hi;
13291332
int32_t tail_lo;
13301333
} arena_coverage_t;
13311334

1332-
typedef struct arena_map3 {
1335+
typedef struct arena_map_bot {
13331336
/* The members tail_hi and tail_lo are accessed together. So, it
13341337
* better to have them as an array of structs, rather than two
13351338
* arrays.
13361339
*/
1337-
arena_coverage_t arenas[MAP3_LENGTH];
1338-
} arena_map3_t;
1340+
arena_coverage_t arenas[MAP_BOT_LENGTH];
1341+
} arena_map_bot_t;
13391342

13401343
#ifdef USE_INTERIOR_NODES
1341-
typedef struct arena_map2 {
1342-
struct arena_map3 *ptrs[MAP2_LENGTH];
1343-
} arena_map2_t;
1344+
typedef struct arena_map_mid {
1345+
struct arena_map_bot *ptrs[MAP_MID_LENGTH];
1346+
} arena_map_mid_t;
13441347

1345-
typedef struct arena_map1 {
1346-
struct arena_map2 *ptrs[MAP1_LENGTH];
1347-
} arena_map1_t;
1348+
typedef struct arena_map_top {
1349+
struct arena_map_mid *ptrs[MAP_TOP_LENGTH];
1350+
} arena_map_top_t;
13481351
#endif
13491352

1350-
/* The root of tree (MAP1) and contains all MAP2 nodes. Note that by
1351-
* initializing like this, the memory should be in the BSS. The OS will
1352-
* only map pages as the MAP2 nodes get used (OS pages are demand loaded
1353-
* as needed).
1353+
/* The root of radix tree. Note that by initializing like this, the memory
1354+
* should be in the BSS. The OS will only memory map pages as the MAP_MID
1355+
* nodes get used (OS pages are demand loaded as needed).
13541356
*/
13551357
#ifdef USE_INTERIOR_NODES
1356-
static arena_map1_t arena_map_root;
1357-
1358-
/* number of used radix tree nodes */
1359-
static int arena_map1_count;
1360-
static int arena_map2_count;
1358+
static arena_map_top_t arena_map_root;
1359+
/* accounting for number of used interior nodes */
1360+
static int arena_map_top_count;
1361+
static int arena_map_mid_count;
1362+
#else
1363+
static arena_map_bot_t arena_map_root;
1364+
#endif
13611365

1362-
/* Return a pointer to a MAP3 node, return NULL if it doesn't exist
1363-
* or it cannot be created */
1364-
static arena_map3_t *
1366+
/* Return a pointer to a bottom tree node, return NULL if it doesn't exist or
1367+
* it cannot be created */
1368+
static arena_map_bot_t *
13651369
arena_map_get(block *p, int create)
13661370
{
1371+
#ifdef USE_INTERIOR_NODES
13671372
/* sanity check that PHYSICAL_BITS is correct */
13681373
assert(HIGH_BITS(p) == HIGH_BITS(&arena_map_root));
1369-
int i1 = MAP1_INDEX(p);
1374+
int i1 = MAP_TOP_INDEX(p);
13701375
if (arena_map_root.ptrs[i1] == NULL) {
13711376
if (!create) {
13721377
return NULL;
13731378
}
1374-
arena_map2_t *n = PyMem_RawCalloc(1, sizeof(arena_map2_t));
1379+
arena_map_mid_t *n = PyMem_RawCalloc(1, sizeof(arena_map_mid_t));
13751380
if (n == NULL) {
13761381
return NULL;
13771382
}
13781383
arena_map_root.ptrs[i1] = n;
1379-
arena_map1_count++;
1384+
arena_map_top_count++;
13801385
}
1381-
int i2 = MAP2_INDEX(p);
1386+
int i2 = MAP_MID_INDEX(p);
13821387
if (arena_map_root.ptrs[i1]->ptrs[i2] == NULL) {
13831388
if (!create) {
13841389
return NULL;
13851390
}
1386-
arena_map3_t *n = PyMem_RawCalloc(1, sizeof(arena_map3_t));
1391+
arena_map_bot_t *n = PyMem_RawCalloc(1, sizeof(arena_map_bot_t));
13871392
if (n == NULL) {
13881393
return NULL;
13891394
}
13901395
arena_map_root.ptrs[i1]->ptrs[i2] = n;
1391-
arena_map2_count++;
1396+
arena_map_mid_count++;
13921397
}
13931398
return arena_map_root.ptrs[i1]->ptrs[i2];
1394-
}
1395-
1396-
#else /* !USE_INTERIOR_NODES */
1397-
static arena_map3_t arena_map_root;
1398-
1399-
/* Return a pointer to a MAP3 node, return NULL if it doesn't exist
1400-
* or it cannot be created */
1401-
static arena_map3_t *
1402-
arena_map_get(block *p, int create)
1403-
{
1399+
#else
14041400
return &arena_map_root;
1405-
}
1406-
14071401
#endif
1402+
}
14081403

14091404

14101405
/* The radix tree only tracks arenas. So, for 16 MiB arenas, we throw
@@ -1436,22 +1431,22 @@ arena_map_mark_used(uintptr_t arena_base, int is_used)
14361431
{
14371432
/* sanity check that PHYSICAL_BITS is correct */
14381433
assert(HIGH_BITS(arena_base) == HIGH_BITS(&arena_map_root));
1439-
arena_map3_t *n_hi = arena_map_get((block *)arena_base, is_used);
1434+
arena_map_bot_t *n_hi = arena_map_get((block *)arena_base, is_used);
14401435
if (n_hi == NULL) {
14411436
assert(is_used); /* otherwise node should already exist */
14421437
return 0; /* failed to allocate space for node */
14431438
}
1444-
int i3 = MAP3_INDEX((block *)arena_base);
1445-
int32_t tail = (int32_t)(arena_base & ARENA_MASK);
1439+
int i3 = MAP_BOT_INDEX((block *)arena_base);
1440+
int32_t tail = (int32_t)(arena_base & ARENA_SIZE_MASK);
14461441
if (tail == 0) {
14471442
/* is ideal arena address */
14481443
n_hi->arenas[i3].tail_hi = is_used ? -1 : 0;
14491444
}
14501445
else {
14511446
/* arena_base address is not ideal (aligned to arena size) and
1452-
* so it potentially covers two MAP3 nodes. Get the MAP3 node
1453-
* for the next arena. Note that it might be in different MAP1
1454-
* and MAP2 nodes as well so we need to call arena_map_get()
1447+
* so it potentially covers two MAP_BOT nodes. Get the MAP_BOT node
1448+
* for the next arena. Note that it might be in different MAP_TOP
1449+
* and MAP_MID nodes as well so we need to call arena_map_get()
14551450
* again (do the full tree traversal).
14561451
*/
14571452
n_hi->arenas[i3].tail_hi = is_used ? tail : 0;
@@ -1461,13 +1456,13 @@ arena_map_mark_used(uintptr_t arena_base, int is_used)
14611456
* must overflow to 0. However, that would mean arena_base was
14621457
* "ideal" and we should not be in this case. */
14631458
assert(arena_base < arena_base_next);
1464-
arena_map3_t *n_lo = arena_map_get((block *)arena_base_next, is_used);
1459+
arena_map_bot_t *n_lo = arena_map_get((block *)arena_base_next, is_used);
14651460
if (n_lo == NULL) {
14661461
assert(is_used); /* otherwise should already exist */
14671462
n_hi->arenas[i3].tail_hi = 0;
14681463
return 0; /* failed to allocate space for node */
14691464
}
1470-
int i3_next = MAP3_INDEX(arena_base_next);
1465+
int i3_next = MAP_BOT_INDEX(arena_base_next);
14711466
n_lo->arenas[i3_next].tail_lo = is_used ? tail : 0;
14721467
}
14731468
return 1;
@@ -1476,17 +1471,17 @@ arena_map_mark_used(uintptr_t arena_base, int is_used)
14761471
/* Return true if 'p' is a pointer inside an obmalloc arena.
14771472
* _PyObject_Free() calls this so it needs to be very fast. */
14781473
static int
1479-
arena_map_is_marked(block *p)
1474+
arena_map_is_used(block *p)
14801475
{
1481-
arena_map3_t *n = arena_map_get(p, 0);
1476+
arena_map_bot_t *n = arena_map_get(p, 0);
14821477
if (n == NULL) {
14831478
return 0;
14841479
}
1485-
int i3 = MAP3_INDEX(p);
1480+
int i3 = MAP_BOT_INDEX(p);
14861481
/* ARENA_BITS must be < 32 so that the tail is a non-negative int32_t. */
14871482
int32_t hi = n->arenas[i3].tail_hi;
14881483
int32_t lo = n->arenas[i3].tail_lo;
1489-
int32_t tail = (int32_t)(AS_UINT(p) & ARENA_MASK);
1484+
int32_t tail = (int32_t)(AS_UINT(p) & ARENA_SIZE_MASK);
14901485
return (tail < lo) || (tail >= hi && hi != 0);
14911486
}
14921487

@@ -1606,7 +1601,7 @@ new_arena(void)
16061601
static bool
16071602
address_in_range(void *p, poolp pool)
16081603
{
1609-
return arena_map_is_marked(p);
1604+
return arena_map_is_used(p);
16101605
}
16111606

16121607

@@ -1954,7 +1949,7 @@ insert_to_freepool(poolp pool)
19541949
ao->nextarena = unused_arena_objects;
19551950
unused_arena_objects = ao;
19561951

1957-
/* mark arena as not under control of obmalloc */
1952+
/* mark arena region as not under control of obmalloc */
19581953
arena_map_mark_used(ao->address, 0);
19591954

19601955
/* Free the entire arena. */
@@ -2200,8 +2195,6 @@ _PyObject_Realloc(void *ctx, void *ptr, size_t nbytes)
22002195
return PyMem_RawRealloc(ptr, nbytes);
22012196
}
22022197

2203-
2204-
22052198
#else /* ! WITH_PYMALLOC */
22062199

22072200
/*==========================================================================*/
@@ -2903,8 +2896,8 @@ _PyObject_DebugMallocStats(FILE *out)
29032896
(void)printone(out, "# arenas highwater mark", narenas_highwater);
29042897
(void)printone(out, "# arenas allocated current", narenas);
29052898
#ifdef USE_INTERIOR_NODES
2906-
(void)printone(out, "# arena map level 1 nodes", arena_map1_count);
2907-
(void)printone(out, "# arena map level 2 nodes", arena_map2_count);
2899+
(void)printone(out, "# arena map top nodes", arena_map_top_count);
2900+
(void)printone(out, "# arena map mid nodes", arena_map_mid_count);
29082901
fputc('\n', out);
29092902
#endif
29102903

@@ -2930,5 +2923,4 @@ _PyObject_DebugMallocStats(FILE *out)
29302923
return 1;
29312924
}
29322925

2933-
29342926
#endif /* #ifdef WITH_PYMALLOC */

0 commit comments

Comments
 (0)