PHP7核心剖析7之Zend引擎執行過程

來源:互聯網
上載者:User
本篇文章的內容介紹的是關於PHP7核心剖析7之Zend引擎執行過程 ,現在分享給大家,有需要的朋友可以參考一下

1.EG(executor_globals/zend_executor_globals)

PHP整個生命週期中最主要的一個結構,是一個全域變數,在main執行前分配(非ZTS下),直到PHP退出,它記錄著當前請求全部的資訊


2.EX(execute_data/zend_execute_data)

在執行過程中最核心的一個結構,每次函數的調用、include/require、eval等都會產生一個新的結構,它表示當前的範圍、代碼的執行位置以及局部變數的分配等等,
#define EX(element)             ((execute_data)->element)struct _zend_execute_data {    const zend_op       *opline;  //指向當前執行的opcode,初始時指向zend_op_array起始位置    zend_execute_data   *call;             /* current call                   */    zval                *return_value;  //傳回值指標    zend_function       *func;          //當前執行的函數(非函數調用時為空白)    zval                 This;          //這個值並不僅僅是物件導向的this,還有另外兩個值也通過這個記錄:call_info + num_args,分別存在zval.u1.reserved、zval.u2.num_args    zend_class_entry    *called_scope;  //當前call的類    zend_execute_data   *prev_execute_data; //函數調用時指向調用位置作用空間    zend_array          *symbol_table; //全域變數符號表#if ZEND_EX_USE_RUN_TIME_CACHE    void               **run_time_cache;   /* cache op_array->run_time_cache */#endif#if ZEND_EX_USE_LITERALS    zval                *literals;  //字面量數組,與func.op_array->literals相同#endif};


3.Zend的執行流程

在Zend VM中zend_execute_data的zend_execute_data.opline,zend_execute_data.prev_execute_data,實現了call/ret
step1: 為當前範圍分配一塊記憶體,充當運行棧,zend_execute_data結構、所有局部變數、中間變數等等都在此記憶體上分配step2: 初始化全域變數符號表,然後將全域執行位置指標EG(current_execute_data)指向step1新分配的zend_execute_data,然後將zend_execute_data.opline指向op_array的起始位置step3: 從EX(opline)開始調用各opcode的C處理handler(即_zend_op.handler),每執行完一條opcode將EX(opline)++繼續執行下一條,直到執行完全部opcode,函數/類成員方法調用、if的執行過程:step3.1: if語句將根據條件的成立與否決定EX(opline) + offset所加的位移量,實現跳轉step3.2: 如果是函數調用,則首先從EG(function_table)中根據function_name取出此function對應的編譯完成的zend_op_array,然後像step1一樣新分配一個zend_execute_data結構,將EG(current_execute_data)賦值給新結構的prev_execute_data,再將EG(current_execute_data)指向新的zend_execute_data,最後從新的zend_execute_data.opline開始執行,切換到函數內部,函數執行完以後將EG(current_execute_data)重新指向EX(prev_execute_data),釋放分配的運行棧,銷毀局部變數,繼續從原來函數調用的位置執行step4: 全部opcode執行完成後將step1分配的記憶體釋放,這個過程會將所有的局部變數"銷毀",執行階段結束


4.運行時緩衝

在執行期間,PHP經常需要根據名稱去不同的雜湊表中尋找常量、函數、類、成員方法、成員屬性等,因此PHP提供了一種緩衝機制用於緩衝根據名稱尋找到的結果,以便再次執行同一opcode時直接複用上次緩衝的值,無需重複尋找,從而提高執行效率。運行時緩衝機制是在同一opcode執行多次的情況下才會生效,特別注意這裡的同一opcode指的並不是opcode值相同,而是指記憶體裡的同一份資料

實際上運行時緩衝是基於所屬opcode中CONST運算元儲存的,也就是說只有包含IS_CONST類型的運算元才有可能用到此機制,其它類型都不會用到,這是因為只有CONST運算元是固定不變的,其它CV、VAR等類型值都不是固定的,既然其值是不固定的那麼緩衝的值也就不是固定的,所以不會針對CONST以外類型的opcode操作進行緩衝

相關推薦:

PHP7核心剖析6之函數

PHP7核心剖析5之 PHP代碼的編譯

PHP7核心剖析4之局部變數,全域變數,常量

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.