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_ALIGNMENTZEND_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

回到顶部