@@ -528,18 +528,17 @@ INTERNAL_HIDDEN void _iso_alloc_destroy_zone_unlocked(iso_alloc_zone_t *zone, bo
528528 POISON_ZONE (zone );
529529 } else {
530530 if (replace == true) {
531- /* The only time we ever destroy a default non-private zone
531+ /* The only time we ever destroy a non-private zone
532532 * is from the destructor so its safe unmap pages */
533533 int16_t zones_used = _root -> zones_used ;
534- size_t size = zone -> chunk_size ;
535534
536535 /* _iso_new_zone() will use _root->zones_used to place
537536 * the new zone at the correct index in _root->zones.
538537 * We will restore this value after the new zone has
539538 * been created */
540539 _root -> zones_used = zone -> index ;
541540 _unmap_zone (zone );
542- _iso_new_zone (size , true);
541+ _iso_new_zone (zone -> chunk_size , true);
543542 _root -> zones_used = zones_used ;
544543 } else {
545544 _unmap_zone (zone );
@@ -989,9 +988,7 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_fit(size_t size) {
989988 LOG_AND_ABORT ("Lookup table should never contain private zones" );
990989 }
991990
992- bool fits = iso_does_zone_fit (zone , size );
993-
994- if (fits == true) {
991+ if (iso_does_zone_fit (zone , size ) == true) {
995992 return zone ;
996993 }
997994
@@ -1027,9 +1024,7 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_fit(size_t size) {
10271024 for (; i < _root -> zones_used ; i ++ ) {
10281025 zone = & _root -> zones [i ];
10291026
1030- bool fits = iso_does_zone_fit (zone , size );
1031-
1032- if (fits == true) {
1027+ if (iso_does_zone_fit (zone , size ) == true) {
10331028 return zone ;
10341029 }
10351030 }
@@ -1214,7 +1209,7 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc_bitslot_from_zone(bit_slot_t bit
12141209 return p ;
12151210}
12161211
1217- /* Populates the thread cache, requires the root is locked and zone is unmasked */
1212+ /* Does not require the root is locked */
12181213INTERNAL_HIDDEN INLINE void populate_zone_cache (iso_alloc_zone_t * zone ) {
12191214 if (UNLIKELY (zone -> internal == false)) {
12201215 return ;
@@ -1331,8 +1326,7 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc(iso_alloc_zone_t *zone, size_t s
13311326#endif
13321327
13331328 /* Allocation requests of SMALL_SZ_MAX bytes or larger are
1334- * handled by the 'big allocation' path. If a zone was
1335- * passed in we abort because its a misuse of the API */
1329+ * handled by the 'big allocation' path. */
13361330 if (LIKELY (size <= SMALL_SZ_MAX )) {
13371331#if FUZZ_MODE
13381332 _verify_all_zones ();
@@ -1344,9 +1338,7 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc(iso_alloc_zone_t *zone, size_t s
13441338 * and this will speed up that operation */
13451339 for (size_t i = 0 ; i < zone_cache_count ; i ++ ) {
13461340 if (zone_cache [i ].chunk_size >= size ) {
1347- bool fit = iso_does_zone_fit (zone_cache [i ].zone , size );
1348-
1349- if (fit == true) {
1341+ if (iso_does_zone_fit (zone_cache [i ].zone , size ) == true) {
13501342 zone = zone_cache [i ].zone ;
13511343 break ;
13521344 }
@@ -1413,13 +1405,7 @@ INTERNAL_HIDDEN ASSUME_ALIGNED void *_iso_alloc(iso_alloc_zone_t *zone, size_t s
14131405
14141406 MASK_ZONE_PTRS (zone );
14151407 UNLOCK_ROOT ();
1416-
1417- /* Zones internal status cannot be converted, it's
1418- * safe to access this bool after unlocking and
1419- * then populating the zone cache */
1420- if (zone -> internal == false) {
1421- populate_zone_cache (zone );
1422- }
1408+ populate_zone_cache (zone );
14231409
14241410 return p ;
14251411 } else {
@@ -1470,13 +1456,7 @@ INTERNAL_HIDDEN iso_alloc_big_zone_t *iso_find_big_zone(void *p) {
14701456 return NULL ;
14711457}
14721458
1473- /* iso_find_zone_bitmap_range and iso_find_zone_range are
1474- * logically identical functions that both return a zone
1475- * for a pointer. The only difference is where the pointer
1476- * addresses, a bitmap or user pages */
1477- INTERNAL_HIDDEN iso_alloc_zone_t * iso_find_zone_bitmap_range (const void * restrict p ) {
1478- iso_alloc_zone_t * zone = NULL ;
1479-
1459+ INTERNAL_HIDDEN iso_alloc_zone_t * search_chunk_lookup_table (const void * restrict p ) {
14801460 /* The chunk lookup table is the fastest way to find a
14811461 * zone given a pointer to a chunk so we check it first */
14821462 uint16_t zone_index = chunk_lookup_table [ADDR_TO_CHUNK_TABLE (p )];
@@ -1485,7 +1465,16 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_bitmap_range(const void *restric
14851465 LOG_AND_ABORT ("Pointer to zone lookup table corrupted at position %zu" , ADDR_TO_CHUNK_TABLE (p ));
14861466 }
14871467
1488- zone = & _root -> zones [zone_index ];
1468+ return & _root -> zones [zone_index ];
1469+ }
1470+
1471+ /* iso_find_zone_bitmap_range and iso_find_zone_range are
1472+ * logically identical functions that both return a zone
1473+ * for a pointer. The only difference is where the pointer
1474+ * addresses, a bitmap or user pages */
1475+ INTERNAL_HIDDEN iso_alloc_zone_t * iso_find_zone_bitmap_range (const void * restrict p ) {
1476+ iso_alloc_zone_t * zone = search_chunk_lookup_table (p );
1477+
14891478 void * bitmap_start = UNMASK_BITMAP_PTR (zone );
14901479
14911480 if (LIKELY (bitmap_start <= p && (bitmap_start + zone -> bitmap_size ) > p )) {
@@ -1495,7 +1484,7 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_bitmap_range(const void *restric
14951484 iso_alloc_zone_t * tmp_zone = NULL ;
14961485
14971486 /* Now we check the MRU thread zone cache */
1498- for (size_t i = 0 ; i < zone_cache_count ; i ++ ) {
1487+ for (int64_t i = 0 ; i < zone_cache_count ; i ++ ) {
14991488 tmp_zone = zone_cache [i ].zone ;
15001489 bitmap_start = UNMASK_BITMAP_PTR (tmp_zone );
15011490
@@ -1507,7 +1496,6 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_bitmap_range(const void *restric
15071496 /* Now we check all zones, this is the slowest path */
15081497 for (int64_t i = 0 ; i < _root -> zones_used ; i ++ ) {
15091498 zone = & _root -> zones [i ];
1510-
15111499 bitmap_start = UNMASK_BITMAP_PTR (zone );
15121500
15131501 if (bitmap_start <= p && (bitmap_start + zone -> bitmap_size ) > p ) {
@@ -1519,27 +1507,19 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_bitmap_range(const void *restric
15191507}
15201508
15211509INTERNAL_HIDDEN iso_alloc_zone_t * iso_find_zone_range (const void * restrict p ) {
1522- iso_alloc_zone_t * zone = NULL ;
1523-
1524- /* The chunk lookup table is the fastest way to find a
1525- * zone given a pointer to a chunk so we check it first */
1526- uint16_t zone_index = chunk_lookup_table [ADDR_TO_CHUNK_TABLE (p )];
1527-
1528- if (UNLIKELY (zone_index > _root -> zones_used )) {
1529- LOG_AND_ABORT ("Pointer to zone lookup table corrupted at position %zu" , ADDR_TO_CHUNK_TABLE (p ));
1530- }
1531-
1532- zone = & _root -> zones [zone_index ];
1510+ iso_alloc_zone_t * zone = search_chunk_lookup_table (p );
15331511 void * user_pages_start = UNMASK_USER_PTR (zone );
15341512
1513+ /* The chunk_lookup_table has a high hit rate. Most
1514+ * calls to this function will return here. */
15351515 if (LIKELY (user_pages_start <= p && (user_pages_start + ZONE_USER_SIZE ) > p )) {
15361516 return zone ;
15371517 }
15381518
15391519 iso_alloc_zone_t * tmp_zone = NULL ;
15401520
15411521 /* Now we check the MRU thread zone cache */
1542- for (size_t i = 0 ; i < zone_cache_count ; i ++ ) {
1522+ for (int64_t i = 0 ; i < zone_cache_count ; i ++ ) {
15431523 tmp_zone = zone_cache [i ].zone ;
15441524 user_pages_start = UNMASK_USER_PTR (tmp_zone );
15451525
@@ -1551,7 +1531,6 @@ INTERNAL_HIDDEN iso_alloc_zone_t *iso_find_zone_range(const void *restrict p) {
15511531 /* Now we check all zones, this is the slowest path */
15521532 for (int64_t i = 0 ; i < _root -> zones_used ; i ++ ) {
15531533 zone = & _root -> zones [i ];
1554-
15551534 user_pages_start = UNMASK_USER_PTR (zone );
15561535
15571536 if (user_pages_start <= p && (user_pages_start + ZONE_USER_SIZE ) > p ) {
@@ -1788,7 +1767,6 @@ INTERNAL_HIDDEN void iso_free_chunk_from_zone(iso_alloc_zone_t *zone, void *rest
17881767#endif
17891768
17901769 POISON_ZONE_CHUNK (zone , p );
1791- populate_zone_cache (zone );
17921770}
17931771
17941772INTERNAL_HIDDEN void _iso_free_from_zone (void * p , iso_alloc_zone_t * zone , bool permanent ) {
@@ -1924,14 +1902,17 @@ INTERNAL_HIDDEN void _iso_free_size(void *p, size_t size) {
19241902 }
19251903
19261904 _iso_free_internal_unlocked (p , false, zone );
1927-
19281905 UNLOCK_ROOT ();
19291906}
19301907
19311908INTERNAL_HIDDEN void _iso_free_internal (void * p , bool permanent ) {
19321909 LOCK_ROOT ();
1933- _iso_free_internal_unlocked (p , permanent , NULL );
1910+ iso_alloc_zone_t * zone = _iso_free_internal_unlocked (p , permanent , NULL );
19341911 UNLOCK_ROOT ();
1912+
1913+ if (zone != NULL ) {
1914+ populate_zone_cache (zone );
1915+ }
19351916}
19361917
19371918INTERNAL_HIDDEN bool _is_zone_retired (iso_alloc_zone_t * zone ) {
@@ -1964,7 +1945,7 @@ INTERNAL_HIDDEN bool _refresh_zone_mem_tags(iso_alloc_zone_t *zone) {
19641945 return false;
19651946}
19661947
1967- INTERNAL_HIDDEN void _iso_free_internal_unlocked (void * p , bool permanent , iso_alloc_zone_t * zone ) {
1948+ INTERNAL_HIDDEN iso_alloc_zone_t * _iso_free_internal_unlocked (void * p , bool permanent , iso_alloc_zone_t * zone ) {
19681949#if FUZZ_MODE
19691950 _verify_all_zones ();
19701951#endif
@@ -2011,6 +1992,7 @@ INTERNAL_HIDDEN void _iso_free_internal_unlocked(void *p, bool permanent, iso_al
20111992 _iso_alloc_ptr_search (p , true);
20121993 }
20131994#endif
1995+ return zone ;
20141996 } else {
20151997 iso_alloc_big_zone_t * big_zone = iso_find_big_zone (p );
20161998
@@ -2019,6 +2001,7 @@ INTERNAL_HIDDEN void _iso_free_internal_unlocked(void *p, bool permanent, iso_al
20192001 }
20202002
20212003 iso_free_big_zone (big_zone , permanent );
2004+ return NULL ;
20222005 }
20232006}
20242007
0 commit comments