This article introduces to you "Analysis of PHP8 underlying kernel source code - array (4)". It has certain reference value. Friends in need can refer to it. I hope it will be helpful to everyone.
Recommended related articles: "Analysis of PHP8 underlying kernel source code - array (1) " "Analysis of PHP8 underlying kernel source code - array (2) " " Parsing PHP8 underlying kernel source code - array (3) 》
In Runningprocess, we already know that the code needs to go through lexical analysis, syntax analysis, compilation and execution of four major steps
PHP 8 will create an array constant during the compilation phase (when the AST abstract syntax tree is compiled into opcode). This array constant, like numeric constants and string constants, is determined and allocated memory during the compilation phase. So the initialization of the array happens during the compilation phase.
PHP’s array initialization code part is as follows
//如果开启zend_debug #if !ZEND_DEBUG && defined(HAVE_BUILTIN_CONSTANT_P) # define zend_new_array(size) \ (__builtin_constant_p(size) ? \ ((((uint32_t)(size)) <= HT_MIN_SIZE) ? \ _zend_new_array_0() \ //走 _zend_new_array_0 : \ _zend_new_array((size)) \ ) \ : \ _zend_new_array((size)) \ ) #else //没有开启 也就是一般模式 走 _zend_new_array # define zend_new_array(size) \ _zend_new_array(size) #endif ZEND_API void ZEND_FASTCALL _zend_hash_init(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent) { _zend_hash_init_int(ht, nSize, pDestructor, persistent); } ZEND_API HashTable* ZEND_FASTCALL _zend_new_array_0(void) { //分配内存空间 HashTable *ht = emalloc(sizeof(HashTable)); //初始化 _zend_hash_init_int(ht, HT_MIN_SIZE, ZVAL_PTR_DTOR, 0); return ht; } //初始化方法 static zend_always_inline void _zend_hash_init_int(HashTable *ht, uint32_t nSize, dtor_func_t pDestructor, zend_bool persistent) { GC_SET_REFCOUNT(ht, 1); GC_TYPE_INFO(ht) = GC_ARRAY | (persistent ? ((GC_PERSISTENT|GC_NOT_COLLECTABLE) << GC_FLAGS_SHIFT) : 0); HT_FLAGS(ht) = HASH_FLAG_UNINITIALIZED; ht->nTableMask = HT_MIN_MASK; HT_SET_DATA_ADDR(ht, &uninitialized_bucket); ht->nNumUsed = 0; ht->nNumOfElements = 0; ht->nInternalPointer = 0; ht->nNextFreeElement = ZEND_LONG_MIN; ht->pDestructor = pDestructor; ht->nTableSize = zend_hash_check_size(nSize); } //初始化 bucket 也就是 ardata ZEND_API void ZEND_FASTCALL zend_hash_real_init(HashTable *ht, zend_bool packed) { IS_CONSISTENT(ht); HT_ASSERT_RC1(ht); //调用 zend_hash_real_init_ex方法 zend_hash_real_init_ex(ht, packed); } //zend_hash_real_init_ex方法 static zend_always_inline void zend_hash_real_init_ex(HashTable *ht, bool packed) { HT_ASSERT_RC1(ht); ZEND_ASSERT(HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED); if (packed) { //如果是packed_array zend_hash_real_init_packed_ex(ht); } else { //如果是 hash_array zend_hash_real_init_mixed_ex(ht); } } //paced_array 初始化bucket 的代码 static zend_always_inline void zend_hash_real_init_packed_ex(HashTable *ht) { void *data; if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) { data = pemalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK), 1); } else if (EXPECTED(ht->nTableSize == HT_MIN_SIZE)) { data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_MIN_MASK)); } else { data = emalloc(HT_SIZE_EX(ht->nTableSize, HT_MIN_MASK)); } HT_SET_DATA_ADDR(ht, data); /* Don't overwrite iterator count. */ ht->u.v.flags = HASH_FLAG_PACKED | HASH_FLAG_STATIC_KEYS; HT_HASH_RESET_PACKED(ht); } //hash_array 初始化bucket的代码 static zend_always_inline void zend_hash_real_init_mixed_ex(HashTable *ht) { void *data; uint32_t nSize = ht->nTableSize; if (UNEXPECTED(GC_FLAGS(ht) & IS_ARRAY_PERSISTENT)) { data = pemalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize)), 1); } else if (EXPECTED(nSize == HT_MIN_SIZE)) { data = emalloc(HT_SIZE_EX(HT_MIN_SIZE, HT_SIZE_TO_MASK(HT_MIN_SIZE))); ht->nTableMask = HT_SIZE_TO_MASK(HT_MIN_SIZE); HT_SET_DATA_ADDR(ht, data); /* Don't overwrite iterator count. */ ht->u.v.flags = HASH_FLAG_STATIC_KEYS; #ifdef __SSE2__ do { __m128i xmm0 = _mm_setzero_si128(); xmm0 = _mm_cmpeq_epi8(xmm0, xmm0); _mm_storeu_si128((__m128i*)&HT_HASH_EX(data, 0), xmm0); _mm_storeu_si128((__m128i*)&HT_HASH_EX(data, 4), xmm0); _mm_storeu_si128((__m128i*)&HT_HASH_EX(data, 8), xmm0); _mm_storeu_si128((__m128i*)&HT_HASH_EX(data, 12), xmm0); } while (0); #elif defined(__aarch64__) do { int32x4_t t = vdupq_n_s32(-1); vst1q_s32((int32_t*)&HT_HASH_EX(data, 0), t); vst1q_s32((int32_t*)&HT_HASH_EX(data, 4), t); vst1q_s32((int32_t*)&HT_HASH_EX(data, 8), t); vst1q_s32((int32_t*)&HT_HASH_EX(data, 12), t); } while (0); #else HT_HASH_EX(data, 0) = -1; HT_HASH_EX(data, 1) = -1; HT_HASH_EX(data, 2) = -1; HT_HASH_EX(data, 3) = -1; HT_HASH_EX(data, 4) = -1; HT_HASH_EX(data, 5) = -1; HT_HASH_EX(data, 6) = -1; HT_HASH_EX(data, 7) = -1; HT_HASH_EX(data, 8) = -1; HT_HASH_EX(data, 9) = -1; HT_HASH_EX(data, 10) = -1; HT_HASH_EX(data, 11) = -1; HT_HASH_EX(data, 12) = -1; HT_HASH_EX(data, 13) = -1; HT_HASH_EX(data, 14) = -1; HT_HASH_EX(data, 15) = -1; #endif return; } else { data = emalloc(HT_SIZE_EX(nSize, HT_SIZE_TO_MASK(nSize))); } ht->nTableMask = HT_SIZE_TO_MASK(nSize); HT_SET_DATA_ADDR(ht, data); HT_FLAGS(ht) = HASH_FLAG_STATIC_KEYS; HT_HASH_RESET(ht); } //数组赋值和更新值 static zend_always_inline zval *_zend_hash_index_add_or_update_i(HashTable *ht, zend_ulong h, zval *pData, uint32_t flag) { uint32_t nIndex; uint32_t idx; Bucket *p; IS_CONSISTENT(ht); HT_ASSERT_RC1(ht); if ((flag & HASH_ADD_NEXT) && h == ZEND_LONG_MIN) { h = 0; } if (HT_FLAGS(ht) & HASH_FLAG_PACKED) { if (h < ht->nNumUsed) { p = ht->arData + h; if (Z_TYPE(p->val) != IS_UNDEF) { replace: if (flag & HASH_ADD) { return NULL; } if (ht->pDestructor) { ht->pDestructor(&p->val); } ZVAL_COPY_VALUE(&p->val, pData); return &p->val; } else { /* we have to keep the order :( */ goto convert_to_hash; } } else if (EXPECTED(h < ht->nTableSize)) { add_to_packed: p = ht->arData + h; /* incremental initialization of empty Buckets */ if ((flag & (HASH_ADD_NEW|HASH_ADD_NEXT)) != (HASH_ADD_NEW|HASH_ADD_NEXT)) { if (h > ht->nNumUsed) { Bucket *q = ht->arData + ht->nNumUsed; while (q != p) { ZVAL_UNDEF(&q->val); q++; } } } ht->nNextFreeElement = ht->nNumUsed = h + 1; goto add; } else if ((h >> 1) < ht->nTableSize && (ht->nTableSize >> 1) < ht->nNumOfElements) { zend_hash_packed_grow(ht); goto add_to_packed; } else { if (ht->nNumUsed >= ht->nTableSize) { ht->nTableSize += ht->nTableSize; } convert_to_hash: zend_hash_packed_to_hash(ht); } } else if (HT_FLAGS(ht) & HASH_FLAG_UNINITIALIZED) { if (h < ht->nTableSize) { zend_hash_real_init_packed_ex(ht); goto add_to_packed; } zend_hash_real_init_mixed(ht); } else { if ((flag & HASH_ADD_NEW) == 0 || ZEND_DEBUG) { p = zend_hash_index_find_bucket(ht, h); if (p) { ZEND_ASSERT((flag & HASH_ADD_NEW) == 0); goto replace; } } ZEND_HASH_IF_FULL_DO_RESIZE(ht);/* If the Hash table is full, resize it */ } idx = ht->nNumUsed++; nIndex = h | ht->nTableMask; p = ht->arData + idx; Z_NEXT(p->val) = HT_HASH(ht, nIndex); HT_HASH(ht, nIndex) = HT_IDX_TO_HASH(idx); if ((zend_long)h >= ht->nNextFreeElement) { ht->nNextFreeElement = (zend_long)h < ZEND_LONG_MAX ? h + 1 : ZEND_LONG_MAX; } add: ht->nNumOfElements++; p->h = h; p->key = NULL; ZVAL_COPY_VALUE(&p->val, pData); return &p->val; }
_zend_hash_init_int The flow chart is as follows





The above is the detailed content of Parsing PHP8 underlying kernel source code - array (4). For more information, please follow other related articles on the PHP Chinese website!

php8加mysql扩展的步骤是:1、安装MySQL客户端库;2、安装PHP 8的开发工具;3、下载MySQL扩展源代码;4、编译和安装MySQL扩展;5、启用MySQL扩展;6、重启Web服务器即可。

php5和php8的区别在性能、语言结构、类型系统、错误处理、异步编程、标准库函数和安全性等方面。详细介绍:1、性能提升,PHP8相对于PHP5来说在性能方面有了巨大的提升,PHP8引入了JIT编译器,可以对一些高频执行的代码进行编译和优化,从而提高运行速度;2、语言结构改进,PHP8引入了一些新的语言结构和功能,PHP8支持命名参数,允许开发者通过参数名而不是参数顺序等等。

本文给大家介绍如何安装apache2.4,以及如何配置php8.0,文中附有图文详细步骤,下面就带大家一起看看怎么安装配置apache2.4+php8.0吧~

PHP8可以使用mysqli和PDO来连接数据库。详细介绍:1、使用mysqli连接数据库,通过传入数据库服务器名称、用户名、密码和数据库名称来进行连接。然后,使用`connect_error`属性来检查连接是否成功,如果连接失败,则输出错误信息。最后,通过调用`close()`方法关闭连接;2、使用PDO连接数据库,通过传入数据库服务器名称、密码和数据库名称来进行连接等等。

php8数据类型的方法有字符串转换为整数、整数转换为字符串、字符串转换为浮点数、浮点数转换为字符串、数组转换为字符串、字符串转换为数组、布尔值转换为整数、整数转换为布尔值和变量类型判断和转换。详细介绍:1、字符串转换为整数包括intval()函数和(int)强制类型转换;2、整数转换为字符串包括strval()函数和(string)强制类型转换;3、字符串转换为浮点数等等。

php求2个数组相同元素的方法:1、创建一个php示例文件;2、定义两个有相同元素的数组;3、使用“array_intersect($array1,$array2)”或“array_intersect_assoc()”方法获取两个数组相同元素即可。

c++初始化数组的方法:1、先定义数组再给数组赋值,语法“数据类型 数组名[length];数组名[下标]=值;”;2、定义数组时初始化数组,语法“数据类型 数组名[length]=[值列表]”。


Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

SublimeText3 Linux new version
SublimeText3 Linux latest version

Notepad++7.3.1
Easy-to-use and free code editor

Atom editor mac version download
The most popular open source editor

WebStorm Mac version
Useful JavaScript development tools

ZendStudio 13.5.1 Mac
Powerful PHP integrated development environment
