@@ -79,9 +79,17 @@ static bool mi_page_list_is_valid(mi_page_t* page, mi_block_t* p) {
7979
8080static bool mi_page_is_valid_init (mi_page_t * page ) {
8181 mi_assert_internal (mi_page_block_size (page ) > 0 );
82+
8283 mi_assert_internal (page -> used <= page -> capacity );
8384 mi_assert_internal (page -> capacity <= page -> reserved );
8485
86+ // [specbot P-NEW-1] block_size_shift must be consistent with block_size (L1, O(1))
87+ mi_assert_internal (page -> block_size_shift == 0 || (mi_page_block_size (page ) == ((size_t )1 << page -> block_size_shift )));
88+ // [specbot P-NEW-2] capacity must be nonzero when blocks are in use (L1, O(1))
89+ mi_assert_internal (page -> used == 0 || page -> capacity > 0 );
90+ // [specbot P-NEW-4] page_start must be non-null when capacity > 0 (L1, O(1))
91+ mi_assert_internal (page -> capacity == 0 || mi_page_start (page ) != NULL );
92+
8593 uint8_t * start = mi_page_start (page );
8694 mi_assert_internal (start == _mi_segment_page_start (_mi_page_segment (page ), page , NULL ));
8795 mi_assert_internal (page -> is_huge == (_mi_page_segment (page )-> kind == MI_SEGMENT_HUGE ));
@@ -90,6 +98,18 @@ static bool mi_page_is_valid_init(mi_page_t* page) {
9098 mi_assert_internal (mi_page_list_is_valid (page ,page -> free ));
9199 mi_assert_internal (mi_page_list_is_valid (page ,page -> local_free ));
92100
101+ // [specbot P-NEW-7] All free list blocks are aligned to block_size (L2, O(n))
102+ {
103+ size_t bsize = mi_page_block_size (page );
104+ uint8_t * pstart = mi_page_start (page );
105+ for (mi_block_t * b = page -> free ; b != NULL ; b = mi_block_next (page , b )) {
106+ mi_assert_internal (((uint8_t * )b - pstart ) % bsize == 0 );
107+ }
108+ for (mi_block_t * b = page -> local_free ; b != NULL ; b = mi_block_next (page , b )) {
109+ mi_assert_internal (((uint8_t * )b - pstart ) % bsize == 0 );
110+ }
111+ }
112+
93113 #if MI_DEBUG > 3 // generally too expensive to check this
94114 if (page -> free_is_zero ) {
95115 const size_t ubsize = mi_page_usable_block_size (page );
@@ -122,6 +142,9 @@ bool _mi_page_is_valid(mi_page_t* page) {
122142 if (mi_page_heap (page )!= NULL ) {
123143 mi_segment_t * segment = _mi_page_segment (page );
124144
145+ // [specbot P-NEW-6] heap_tag must match owning heap's tag (L1, O(1))
146+ mi_assert_internal (page -> heap_tag == mi_page_heap (page )-> tag );
147+
125148 mi_assert_internal (!_mi_process_is_initialized || segment -> thread_id == 0 || segment -> thread_id == mi_page_heap (page )-> thread_id );
126149 #if MI_HUGE_PAGE_ABANDON
127150 if (segment -> kind != MI_SEGMENT_HUGE )
0 commit comments