加入收藏 | 设为首页 | 会员中心 | 我要投稿 莱芜站长网 (https://www.0634zz.com/)- 云连接、建站、智能边缘云、设备管理、大数据!
当前位置: 首页 > 编程开发 > PHP > 正文

聊一聊关于php源码中refcount的疑问

发布时间:2023-02-16 12:47:31 所属栏目:PHP 来源:互联网
导读:这篇文章主要给大家介绍了关于对php源码中refcount的相关疑问,文中通过实例代码介绍的非常详细,对大家的学习或工作具有一定的参考学习价值,需要的朋友可以参考下 在浏览PHP源码的时候,在众多的*.stub.php中,发现了这样的注释,@refcount 1。 通过翻看build

      F1("bcdiv", MAY_BE_STRING),
      F1("bcmod", MAY_BE_STRING),
      F1("bcpowmod", MAY_BE_STRING),
      F1("bcpow", MAY_BE_STRING),
      F1("bcsqrt", MAY_BE_STRING),
      FN("bzopen", MAY_BE_RESOURCE|MAY_BE_FALSE),
      F1("bzerror", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING),
      F1("cal_from_jd", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_NULL),
      F1("cal_info", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_LONG|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY),
      F1("curl_copy_handle", MAY_BE_OBJECT|MAY_BE_FALSE),
      //...
  };
  再去看看F1和FN的宏定义。

  typedef struct _func_info_t {
      const char *name;
      unsigned    name_len;
      uint32_t    info;
      info_func_t info_func;
  } func_info_t;
  
  #define F0(name, info)
      {name, sizeof(name)-1, (info), NULL}
  #define F1(name, info)
      {name, sizeof(name)-1, (MAY_BE_RC1 | (info)), NULL}
  #define FN(name, info)
      {name, sizeof(name)-1, (MAY_BE_RC1 | MAY_BE_RCN | (info)), NULL}
  #define FC(name, callback)
      {name, sizeof(name)-1, 0, callback}
  仅仅是设置了不同的type mask,F1设置了MAY_BE_RC1,FN设置了MAY_BE_RCN | MAY_BE_RC1。
 
  依然一头雾水,但是通过目录名,我依稀能猜出这跟性能优化有关,跟JIT有关系。我决定继续追查下去,看看这些初始化后的结构体在哪里使用过。

  #ifdef ZEND_JIT_USE_RC_INFERENCE
      /* Refcount may be increased by RETURN opcode */
      if ((info & MAY_BE_RC1) && !(info & MAY_BE_RCN)) {
          for (j = 0; j < ssa->cfg.blocks_count; j++) {
              if ((ssa->cfg.blocks[j].flags & ZEND_BB_REACHABLE) &&
                  ssa->cfg.blocks[j].len > 0) {
                  const zend_op *opline = op_array->opcodes + ssa->cfg.blocks[j].start + ssa->cfg.blocks[j].len - 1;
  
                  if (opline->opcode == ZEND_RETURN) {
                      if (opline->op1_type == IS_CV && opline->op1.var == EX_NUM_TO_VAR(var)) {
                          info |= MAY_BE_RCN;
                          break;
                      }
                  }
              }
          }
      }
  #endif
  如果返回值的引用计数是1,而不是N的时候,并且开启了返回值引用计数推导功能,就走这段代码。这段代码又涉及到所谓SSA,静态单赋值的编译器设计方式。
 
  在编译器设计中,静态单一赋值形式(通常缩写为SSA形式或简称SSA)是中间表示(IR)的属性,它要求每个变量只分配一次,并且每个变量在使用之前定义。原始IR中的现有变量被拆分为版本,在教科书中,新变量通常由原始名称用下标表示,以便每次定义都有自己的版本。在SSA形式中,use-def链是显式的,每个包含一个元素。

(编辑:莱芜站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

推荐文章
    热点阅读