zend_objects_store_put

coder_study發表於2019-11-04

本文支援建立最簡單的物件
實現兩個大的功能:
1把新物件新增進入 EG(objects_store),並獲得編號
涉及到插入到什麼位置,並檢測是否已經用完空間,用完則擴容;
2編號賦值給新的物件handle

struct _zend_object {
    zend_refcounted_h gc;    //引用計數
    uint32_t          handle; // TODO: may be removed 
    zend_class_entry *ce;  //所屬類
    const zend_object_handlers *handlers;  //物件操作處理函式
    HashTable        *properties;
    zval              properties_table[1];  //普通屬性值陣列
};
typedef struct _zend_objects_store {
    zend_object **object_buckets; //物件陣列
    uint32_t top;  //當前全部object數
    uint32_t size; //object_buckets大小
    int free_list_head; //第一個可用object_buckets位置
} zend_objects_store;
ZEND_API void zend_objects_store_put(zend_object *object)  
{
    int handle;

    if (EG(objects_store).free_list_head != -1) {
        //主要是gc中會將中間一些object銷燬,空出一些bucket位置
        //然後free_list_head就指向了第一個可用的bucket位置
        //後面可用的儲存在第一個空閒bucket的handle中
        handle = EG(objects_store).free_list_head;
        EG(objects_store).free_list_head = GET_OBJ_BUCKET_NUMBER(EG(objects_store).object_buckets[handle]);
    } else {
        if (EG(objects_store).top == EG(objects_store).size) {
            //擴容
            uint32_t new_size = 2 * EG(objects_store).size;
            EG(objects_store).object_buckets = (zend_object **) erealloc(EG(objects_store).object_buckets, new_size * sizeof(zend_object*));
            /* Assign size after realloc, in case it fails */
            EG(objects_store).size = new_size;
        }
        //遞增加1
        handle = EG(objects_store).top++;
    }
    object->handle = handle; // 物件編號
    //例項化一個物件就會將其插入到object_buckets陣列中 ******
    EG(objects_store).object_buckets[handle] = object;
}
本作品採用《CC 協議》,轉載必須註明作者和本文連結