1
1
#include "Python.h"
2
2
3
+ #include <stdbool.h>
4
+
3
5
4
6
/* Defined in tracemalloc.c */
5
7
extern void _PyMem_DumpTraceback (int fd , const void * ptr );
@@ -37,16 +39,14 @@ static void _PyMem_DebugCheckAddress(char api_id, const void *p);
37
39
#if defined(__has_feature ) /* Clang */
38
40
#if __has_feature (address_sanitizer ) /* is ASAN enabled? */
39
41
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
40
- __attribute__((no_address_safety_analysis)) \
41
- __attribute__ ((noinline))
42
+ __attribute__((no_address_safety_analysis))
42
43
#else
43
44
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
44
45
#endif
45
46
#else
46
47
#if defined(__SANITIZE_ADDRESS__ ) /* GCC 4.8.x, is ASAN enabled? */
47
48
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS \
48
- __attribute__((no_address_safety_analysis)) \
49
- __attribute__ ((noinline))
49
+ __attribute__((no_address_safety_analysis))
50
50
#else
51
51
#define ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
52
52
#endif
@@ -1124,13 +1124,13 @@ new_arena(void)
1124
1124
}
1125
1125
1126
1126
/*
1127
- Py_ADDRESS_IN_RANGE (P, POOL)
1127
+ address_in_range (P, POOL)
1128
1128
1129
1129
Return true if and only if P is an address that was allocated by pymalloc.
1130
1130
POOL must be the pool address associated with P, i.e., POOL = POOL_ADDR(P)
1131
1131
(the caller is asked to compute this because the macro expands POOL more than
1132
1132
once, and for efficiency it's best for the caller to assign POOL_ADDR(P) to a
1133
- variable and pass the latter to the macro; because Py_ADDRESS_IN_RANGE is
1133
+ variable and pass the latter to the macro; because address_in_range is
1134
1134
called on every alloc/realloc/free, micro-efficiency is important here).
1135
1135
1136
1136
Tricky: Let B be the arena base address associated with the pool, B =
@@ -1155,7 +1155,7 @@ arenas[(POOL)->arenaindex]. Suppose obmalloc controls P. Then (barring wild
1155
1155
stores, etc), POOL is the correct address of P's pool, AO.address is the
1156
1156
correct base address of the pool's arena, and P must be within ARENA_SIZE of
1157
1157
AO.address. In addition, AO.address is not 0 (no arena can start at address 0
1158
- (NULL)). Therefore Py_ADDRESS_IN_RANGE correctly reports that obmalloc
1158
+ (NULL)). Therefore address_in_range correctly reports that obmalloc
1159
1159
controls P.
1160
1160
1161
1161
Now suppose obmalloc does not control P (e.g., P was obtained via a direct
@@ -1196,51 +1196,21 @@ that this test determines whether an arbitrary address is controlled by
1196
1196
obmalloc in a small constant time, independent of the number of arenas
1197
1197
obmalloc controls. Since this test is needed at every entry point, it's
1198
1198
extremely desirable that it be this fast.
1199
-
1200
- Since Py_ADDRESS_IN_RANGE may be reading from memory which was not allocated
1201
- by Python, it is important that (POOL)->arenaindex is read only once, as
1202
- another thread may be concurrently modifying the value without holding the
1203
- GIL. To accomplish this, the arenaindex_temp variable is used to store
1204
- (POOL)->arenaindex for the duration of the Py_ADDRESS_IN_RANGE macro's
1205
- execution. The caller of the macro is responsible for declaring this
1206
- variable.
1207
1199
*/
1208
- #define Py_ADDRESS_IN_RANGE (P , POOL ) \
1209
- ((arenaindex_temp = (POOL)->arenaindex) < maxarenas && \
1210
- (uptr)(P) - arenas[arenaindex_temp].address < (uptr)ARENA_SIZE && \
1211
- arenas[arenaindex_temp].address != 0)
1212
-
1213
-
1214
- /* This is only useful when running memory debuggers such as
1215
- * Purify or Valgrind. Uncomment to use.
1216
- *
1217
- #define Py_USING_MEMORY_DEBUGGER
1218
- */
1219
-
1220
- #ifdef Py_USING_MEMORY_DEBUGGER
1221
-
1222
- /* Py_ADDRESS_IN_RANGE may access uninitialized memory by design
1223
- * This leads to thousands of spurious warnings when using
1224
- * Purify or Valgrind. By making a function, we can easily
1225
- * suppress the uninitialized memory reads in this one function.
1226
- * So we won't ignore real errors elsewhere.
1227
- *
1228
- * Disable the macro and use a function.
1229
- */
1230
-
1231
- #undef Py_ADDRESS_IN_RANGE
1232
-
1233
- #if defined(__GNUC__ ) && ((__GNUC__ == 3 ) && (__GNUC_MINOR__ >= 1 ) || \
1234
- (__GNUC__ >= 4 ))
1235
- #define Py_NO_INLINE __attribute__((__noinline__))
1236
- #else
1237
- #define Py_NO_INLINE
1238
- #endif
1239
1200
1240
- /* Don't make static, to try to ensure this isn't inlined. */
1241
- int Py_ADDRESS_IN_RANGE (void * P , poolp pool ) Py_NO_INLINE ;
1242
- #undef Py_NO_INLINE
1243
- #endif
1201
+ static bool ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
1202
+ address_in_range (void * p , poolp pool )
1203
+ {
1204
+ // Since address_in_range may be reading from memory which was not allocated
1205
+ // by Python, it is important that pool->arenaindex is read only once, as
1206
+ // another thread may be concurrently modifying the value without holding
1207
+ // the GIL. The following dance forces the compiler to read pool->arenaindex
1208
+ // only once.
1209
+ uint arenaindex = * ((volatile uint * )& pool -> arenaindex );
1210
+ return arenaindex < maxarenas &&
1211
+ (uptr )p - arenas [arenaindex ].address < ARENA_SIZE &&
1212
+ arenas [arenaindex ].address != 0 ;
1213
+ }
1244
1214
1245
1215
/*==========================================================================*/
1246
1216
@@ -1485,17 +1455,13 @@ _PyObject_Calloc(void *ctx, size_t nelem, size_t elsize)
1485
1455
1486
1456
/* free */
1487
1457
1488
- ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
1489
1458
static void
1490
1459
_PyObject_Free (void * ctx , void * p )
1491
1460
{
1492
1461
poolp pool ;
1493
1462
block * lastfree ;
1494
1463
poolp next , prev ;
1495
1464
uint size ;
1496
- #ifndef Py_USING_MEMORY_DEBUGGER
1497
- uint arenaindex_temp ;
1498
- #endif
1499
1465
1500
1466
if (p == NULL ) /* free(NULL) has no effect */
1501
1467
return ;
@@ -1508,7 +1474,7 @@ _PyObject_Free(void *ctx, void *p)
1508
1474
#endif
1509
1475
1510
1476
pool = POOL_ADDR (p );
1511
- if (Py_ADDRESS_IN_RANGE (p , pool )) {
1477
+ if (address_in_range (p , pool )) {
1512
1478
/* We allocated this address. */
1513
1479
LOCK ();
1514
1480
/* Link p to the start of the pool's freeblock list. Since
@@ -1714,16 +1680,12 @@ _PyObject_Free(void *ctx, void *p)
1714
1680
* return a non-NULL result.
1715
1681
*/
1716
1682
1717
- ATTRIBUTE_NO_ADDRESS_SAFETY_ANALYSIS
1718
1683
static void *
1719
1684
_PyObject_Realloc (void * ctx , void * p , size_t nbytes )
1720
1685
{
1721
1686
void * bp ;
1722
1687
poolp pool ;
1723
1688
size_t size ;
1724
- #ifndef Py_USING_MEMORY_DEBUGGER
1725
- uint arenaindex_temp ;
1726
- #endif
1727
1689
1728
1690
if (p == NULL )
1729
1691
return _PyObject_Alloc (0 , ctx , 1 , nbytes );
@@ -1735,7 +1697,7 @@ _PyObject_Realloc(void *ctx, void *p, size_t nbytes)
1735
1697
#endif
1736
1698
1737
1699
pool = POOL_ADDR (p );
1738
- if (Py_ADDRESS_IN_RANGE (p , pool )) {
1700
+ if (address_in_range (p , pool )) {
1739
1701
/* We're in charge of this block */
1740
1702
size = INDEX2SIZE (pool -> szidx );
1741
1703
if (nbytes <= size ) {
@@ -2432,19 +2394,3 @@ _PyObject_DebugMallocStats(FILE *out)
2432
2394
}
2433
2395
2434
2396
#endif /* #ifdef WITH_PYMALLOC */
2435
-
2436
-
2437
- #ifdef Py_USING_MEMORY_DEBUGGER
2438
- /* Make this function last so gcc won't inline it since the definition is
2439
- * after the reference.
2440
- */
2441
- int
2442
- Py_ADDRESS_IN_RANGE (void * P , poolp pool )
2443
- {
2444
- uint arenaindex_temp = pool -> arenaindex ;
2445
-
2446
- return arenaindex_temp < maxarenas &&
2447
- (uptr )P - arenas [arenaindex_temp ].address < (uptr )ARENA_SIZE &&
2448
- arenas [arenaindex_temp ].address != 0 ;
2449
- }
2450
- #endif
0 commit comments