ZEND_MM_SMALL_SIZE 详细讲解
宏 ZEND_MM_SMALL_SIZE(true_size)
是判断 true_size
大小是否符合小块大小。可以理解为一个boolean
值
#define ZEND_MM_SMALL_SIZE(true_size) (true_size < ZEND_MM_MAX_SMALL_SIZE)
宏 ZEND_MM_MAX_SMALL_SIZE
表示小块内存最大能容纳的数据的大小
#define ZEND_MM_MAX_SMALL_SIZE ((ZEND_MM_NUM_BUCKETS<<ZEND_MM_ALIGNMENT_LOG2)+ZEND_MM_ALIGNED_MIN_HEADER_SIZE)
这个计算过程有点复杂,拆开来看
#define ZEND_MM_NUM_BUCKETS (sizeof(size_t) << 3)
#define ZEND_MM_ALIGNMENT_LOG2 3
#define ZEND_MM_ALIGNED_MIN_HEADER_SIZE (ZEND_MM_MIN_ALLOC_BLOCK_SIZE>ZEND_MM_ALIGNED_FREE_HEADER_SIZE?ZEND_MM_MIN_ALLOC_BLOCK_SIZE:ZEND_MM_ALIGNED_FREE_HEADER_SIZE) // 最小需要的free_block 的头部的大小,也就是ZEND_MM_MIN_ALLOC_BLOCK_SIZE和ZEND_MM_ALIGNED_FREE_HEADER_SIZE 二者之间最大的值
崩溃了,一环套一环,宏 ZEND_MM_ALIGNED_MIN_HEADER_SIZE
定义稍微复杂,继续拆分这个宏
#define ZEND_MM_MIN_ALLOC_BLOCK_SIZE ZEND_MM_ALIGNED_SIZE(ZEND_MM_ALIGNED_HEADER_SIZE + END_MAGIC_SIZE) // 最小需要分配的块的大小
#define ZEND_MM_ALIGNED_FREE_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_small_free_block)) // 结构体zend_mm_small_free_block 的大小,但就这个宏而言无特殊的逻辑含义 56
// 拆分 宏 ZEND_MM_MIN_ALLOC_BLOCK_SIZE
#define ZEND_MM_ALIGNED_HEADER_SIZE ZEND_MM_ALIGNED_SIZE(sizeof(zend_mm_block)) // free_block 头部大小
#if ZEND_MM_HEAP_PROTECTION
# define END_MAGIC_SIZE sizeof(unsigned int)
#else
# define END_MAGIC_SIZE 0
#endif
衍生出了这样的两个宏定义,现在看应该就剩下 宏 ZEND_MM_ALIGNED_SIZE(size)
了。看这个宏的定义
#define ZEND_MM_ALIGNED_SIZE(size) (((size) + ZEND_MM_ALIGNMENT - 1) & ZEND_MM_ALIGNMENT_MASK)
这里面又涉及到两个宏ZEND_MM_ALIGNMENT
和 ZEND_MM_ALIGNMENT_MASK
看起来这两个宏是有些关联的
#define ZEND_MM_ALIGNMENT 8
#define ZEND_MM_ALIGNMENT_MASK ~(ZEND_MM_ALIGNMENT-1)
好了,到这里已经到尽头了。现在我们往回带入。通过简单的二进制的计算,可以发现 宏 ZEND_MM_ALIGNED_SIZE(size)
是用来将size大小进行对齐的。即将 size 对齐为大于size的8的最小整数倍。举个例子:
size = 256
256: 100000000 ZEND_MM_ALIGNED_SIZE(256) => (((256)+8-1) & ~(8-1)) 转换成二进制为 100000000 + 000000111 & 111111000 = 100000000 256 本身能被 8 整除, 所以对齐之后还是 256
size = 257
257: 100000001 ZEND_MM_ALIGNED_SIZE(257) => (((257)+8-1) & ~(8-1)) 转换成二进制为 100000001 + 000000111 & 111111000 = 100001000 => 264 为 8 的倍数
size = 263
263: 100000111 ZEND_MM_ALIGNED_SIZE(263) => (((263)+8-1) & ~(8-1)) 转换成二进制为 100000111 + 000000111 & 111111000 = 100001000 => 264 为 8 的倍数
好了,现在清楚了宏ZEND_MM_ALIGNED_SIZE(size)
的作用。那继续往回带入可以得出中间很多宏的值和一些特殊含义,已经在上面代码里写了注释。 最终可以计算出宏 ZEND_MM_MAX_SMALL_SIZE
,在我的机器上为 544 。 最终也就能理解了宏ZEND_MM_SMALL_SIZE
。
本文转载自:迹忆客(https://www.jiyik.com)
以上是 ZEND_MM_SMALL_SIZE 详细讲解 的全部内容, 来源链接: utcz.com/z/290196.html