• <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>
  • php代碼性能調優profile利器xhprof工作原理淺析(2)

    發表于:2013-01-30來源:Csdn作者:yzongyu點擊數: 標簽:xhprof
    typedef struct _zval_struct zval; typedef struct _zend_class_entry zend_class_entry; typedef union _zvalue_value { long lval; /* long value */ double dval; /* double value */ struct { char *val; int l

      typedef struct _zval_struct zval;

      typedef struct _zend_class_entry zend_class_entry;

      typedef union _zvalue_value {

      long lval; /* long value */

      double dval; /* double value */

      struct {

      char *val;

      int len;

      } str;

      HashTable *ht; /* hash table value */

      struct {

      zend_class_entry *ce;

      HashTable *properties;

      } obj;

      } zvalue_value;

      struct _zval_struct {

      /* Variable information */

      zvalue_value value; /* value */

      zend_uchar type; /* active type 見3*/

      zend_uchar is_ref; /*是否為引用*/

      zend_ushort refcount;

      };

      (zend.h 208行)

      上面的union _zvalue_value就是定義的聯合體。它里面包含了常見的long、double,字符串型(以結構體的方式,分別有字符串首地址,字符串長度)、哈希表、類結構體(object)根據用戶不同的賦值,該容器對處理的外部變量呈現不同的類型。zend將外部變量的值,type,是否被引用,引用計數等信息就存儲在封裝的_zval_struct結構體中。這就是為什么php可以不用在需要使用變量的時候,不用先定義可以直接用的原因。

      好,現在回來繼續看xhprof.c文件。

      PHP_FUNCTION(xhprof_enable) {

      long xhprof_flags = 0; /* XHProf flags */

      zval *optional_array = NULL; /* optional array arg: for future use */

      if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC,

      "|lz", &xhprof_flags, &optional_array) == FAILURE) {

      return;

      }

      hp_get_ignored_functions_from_arg(optional_array);

      hp_begin(XHPROF_MODE_HIERARCHICAL, xhprof_flags TSRMLS_CC);

      }在這個函數定義中,執行完需要ignore的函數的邏輯之后,進入hp_begin的執行,這個函數的原型為:

      static void hp_begin(long level, long xhprof_flags TSRMLS_DC) {

      if (!hp_globals.enabled) {

      int hp_profile_flag = 1;

      hp_globals.enabled = 1;

      hp_globals.xhprof_flags = (uint32)xhprof_flags;

      /* Replace zend_compile with our proxy */

      _zend_compile_file = zend_compile_file;

      zend_compile_file = hp_compile_file;

      /* Replace zend_execute with our proxy */

      _zend_execute = zend_execute;

      zend_execute = hp_execute;

      /* Replace zend_execute_internal with our proxy */

      _zend_execute_internal = zend_execute_internal;

      if (!(hp_globals.xhprof_flags & XHPROF_FLAGS_NO_BUILTINS)) {

      /* if NO_BUILTINS is not set (i.e. user wants to profile builtins),

      * then we intercept internal (builtin) function calls.

      */

      zend_execute_internal = hp_execute_internal;

      }

      /* Initialize with the dummy mode first Having these dummy callbacks saves

      * us from checking if any of the callbacks are NULL everywhere. */

      hp_globals.mode_cb.init_cb = hp_mode_dummy_init_cb;

      hp_globals.mode_cb.exit_cb = hp_mode_dummy_exit_cb;

      hp_globals.mode_cb.begin_fn_cb = hp_mode_dummy_beginfn_cb;

      hp_globals.mode_cb.end_fn_cb = hp_mode_dummy_endfn_cb;

      /* Register the appropriate callback functions Override just a subset of

      * all the callbacks is OK. */

      switch(level) {

      case XHPROF_MODE_HIERARCHICAL:

      hp_globals.mode_cb.begin_fn_cb = hp_mode_hier_beginfn_cb;

      hp_globals.mode_cb.end_fn_cb = hp_mode_hier_endfn_cb;

      break;

      case XHPROF_MODE_SAMPLED:

      ...(后面的函數內容都大同小異,就不再全部貼上來了,有興趣的可以到xhprof/extension里面去查看xhprof.c)

      這里可以看到

      if (!hp_globals.enabled) {...如果xhprof的enable為打開的狀態,則進入該分支流程,下面做了對應的對zend的處理方法的replace,比如,zend_compile_file,zend_execute,zend_execute_internal etc。而這些zend的方法作用分別是完成文件的compile和execute、后面帶有internal的是對內部函數的執行。xhprof就是通過對zend的內部函數的replace,然后在對應的zend處理函數中進行所需要的數據的抓取和存儲,這個可以在被replace之后的hp_execute (zend_op_array *ops TSRMLS_DC) 里面看到

      BEGIN_PROFILING(&hp_globals.entries, func, hp_profile_flag);之后就是進入了xhprof本身的自定義的一些任務的開始了,比如初始化一些內存空間來做好后面需要抓取的數據的存儲,對于抓取到的profiling data的數據的處理等

      在最后結束的時候(也就是disable的時候)

      xhprof通過

      /* Remove proxies, restore the originals */

      zend_execute = _zend_execute;

      zend_execute_internal = _zend_execute_internal;

      zend_compile_file = _zend_compile_file;

      對清理掉xhprof對zend的相關三個函數的proxies,從而關閉了xhprof對php代碼執行的數據的收集工作。大體上就是這么多

      由于本身能力有限,所以當中不免會引入一些錯誤和不足,誠邀您對當中的不足、錯誤之處進行補充和指出,謝謝

    原文轉自:http://blog.csdn.net/yzongyu/article/details/8457209

    老湿亚洲永久精品ww47香蕉图片_日韩欧美中文字幕北美法律_国产AV永久无码天堂影院_久久婷婷综合色丁香五月

  • <ruby id="5koa6"></ruby>
    <ruby id="5koa6"><option id="5koa6"><thead id="5koa6"></thead></option></ruby>

    <progress id="5koa6"></progress>

  • <strong id="5koa6"></strong>