Skip to content

Commit 9b2886f

Browse files
committed
wip: 32-bit version
1 parent 3492ef6 commit 9b2886f

File tree

1 file changed

+57
-11
lines changed

1 file changed

+57
-11
lines changed

Objects/obmalloc.c

Lines changed: 57 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -841,6 +841,7 @@ static int running_on_valgrind = -1;
841841
#if SIZEOF_VOID_P == 8
842842
#define WITH_RADIX_TREE
843843
#endif
844+
#define WITH_RADIX_TREE
844845

845846
/*
846847
* Alignment of addresses returned to the user. 8-bytes alignment works
@@ -2807,16 +2808,41 @@ _PyObject_DebugMallocStats(FILE *out)
28072808
20 -> ideal aligned arena
28082809
----
28092810
64
2811+
2812+
key format (2^20 arena size)
2813+
12 -> MAP3
2814+
20 -> ideal aligned arena
2815+
----
2816+
32
2817+
28102818
*/
28112819

2820+
#if SIZEOF_VOID_P == 8
28122821
/* number of bits in a pointer */
28132822
#define BITS 64
28142823

2815-
#if SIZEOF_VOID_P != 8
2816-
/* Currently this code works for 64-bit pointers only. For 32-bits, we
2817-
* could use a two-layer tree but it hasn't been implemented yet. */
2818-
#error "Radix tree requires 64-bit pointers."
2819-
#endif
2824+
/* Current 64-bit processors are limited to 48-bit physical addresses. For
2825+
* now, the top 17 bits of addresses will all be equal to bit 2**47. If that
2826+
* changes in the future, this must be adjusted upwards.
2827+
*/
2828+
#define PHYSICAL_BITS 48
2829+
2830+
/* need more layers of tree */
2831+
#define USE_INTERIOR_NODES
2832+
2833+
#define arena_root_t arena_map1_t
2834+
2835+
#elif SIZEOF_VOID_P == 4
2836+
#define BITS 32
2837+
#define PHYSICAL_BITS 32
2838+
2839+
#else
2840+
2841+
/* Currently this code works for 64-bit or 32-bit pointers only. */
2842+
#error "obmalloc radix tree requires 64-bit or 32-bit pointers."
2843+
2844+
#endif /* SIZEOF_VOID_P */
2845+
28202846

28212847
#define ARENA_MASK (ARENA_SIZE - 1)
28222848

@@ -2825,14 +2851,12 @@ _PyObject_DebugMallocStats(FILE *out)
28252851
# error "arena size must be < 2^32"
28262852
#endif
28272853

2828-
/* Current 64-bit processors are limited to 48-bit physical addresses. For
2829-
* now, the top 17 bits of addresses will all be equal to bit 2**47. If that
2830-
* changes in the future, this must be adjusted upwards.
2831-
*/
2832-
#define PHYSICAL_BITS 48
2833-
2854+
#ifdef USE_INTERIOR_NODES
28342855
/* bits used for MAP1 and MAP2 nodes */
28352856
#define INTERIOR_BITS ((PHYSICAL_BITS - ARENA_BITS + 2) / 3)
2857+
#else
2858+
#define INTERIOR_BITS 0
2859+
#endif
28362860

28372861
#define MAP1_BITS INTERIOR_BITS
28382862
#define MAP1_LENGTH (1 << MAP1_BITS)
@@ -2854,7 +2878,12 @@ _PyObject_DebugMallocStats(FILE *out)
28542878
#define MAP3_INDEX(p) ((AS_UINT(p) >> MAP3_SHIFT) & MAP3_MASK)
28552879
#define MAP2_INDEX(p) ((AS_UINT(p) >> MAP2_SHIFT) & MAP2_MASK)
28562880
#define MAP1_INDEX(p) ((AS_UINT(p) >> MAP1_SHIFT) & MAP1_MASK)
2881+
#if PHYSICAL_BITS > BITS
28572882
#define HIGH_BITS(p) (AS_UINT(p) >> PHYSICAL_BITS)
2883+
#else
2884+
#define HIGH_BITS(p) 0
2885+
#endif
2886+
28582887

28592888
/* See arena_map_mark_used() for the meaning of these members. */
28602889
typedef struct {
@@ -2870,19 +2899,22 @@ typedef struct arena_map3 {
28702899
arena_coverage_t arenas[MAP3_LENGTH];
28712900
} arena_map3_t;
28722901

2902+
#ifdef USE_INTERIOR_NODES
28732903
typedef struct arena_map2 {
28742904
struct arena_map3 *ptrs[MAP2_LENGTH];
28752905
} arena_map2_t;
28762906

28772907
typedef struct arena_map1 {
28782908
struct arena_map2 *ptrs[MAP1_LENGTH];
28792909
} arena_map1_t;
2910+
#endif
28802911

28812912
/* The root of tree (MAP1) and contains all MAP2 nodes. Note that by
28822913
* initializing like this, the memory should be in the BSS. The OS will
28832914
* only map pages as the MAP2 nodes get used (OS pages are demand loaded
28842915
* as needed).
28852916
*/
2917+
#ifdef USE_INTERIOR_NODES
28862918
static arena_map1_t arena_map_root;
28872919

28882920
/* Return a pointer to a MAP3 node, return NULL if it doesn't exist
@@ -2919,6 +2951,20 @@ arena_map_get(block *p, int create)
29192951
return arena_map_root.ptrs[i1]->ptrs[i2];
29202952
}
29212953

2954+
#else /* !USE_INTERIOR_NODES */
2955+
static arena_map3_t arena_map_root;
2956+
2957+
/* Return a pointer to a MAP3 node, return NULL if it doesn't exist
2958+
* or it cannot be created */
2959+
static arena_map3_t *
2960+
arena_map_get(block *p, int create)
2961+
{
2962+
return &arena_map_root;
2963+
}
2964+
2965+
#endif
2966+
2967+
29222968
/* The radix tree only tracks arenas. So, for 16 MiB arenas, we throw
29232969
* away 24 bits of the address. That reduces the space requirement of
29242970
* the tree compared to similar radix tree page-map schemes. In

0 commit comments

Comments
 (0)