PHP7源码笔记一-阿里云开发者社区

开发者社区> 开发与运维> 正文

PHP7源码笔记一

简介:

1.builtin types

基本定义在Zend/zend_types.h和Zend/zend.h中
主要的几种:

  • 原始类型:zend_bool,zend_uchar,zend_intptr_t..
  • 封装的用户直接接触的类型
    zend_string,zend_array(HashTable),zend_object,zend_resource,zend_function..
  • 内部使用:
    zval,zend_value,zend_class_entry,zend_reference,zend_refcounted,zend_ast,zend_ast_ref,Bucket,zend_execute_data,HashTableIterator..

基本上是围绕以上几种类型构建整个数据操作的,尤其是
zend_object,HashTable,zend_string,zval的操作很常用


2.a couple of important globals

整个PHP环境和Zend环境会涉及多个全局变量,下面是几个比较重要的:

  • php_core_globals core_globals(main/php_globals.h) ==> PG PHP调度sapi和zend engine的整个环境的全局变量存放位置
  • sapi_globals_struct sapi_globals(main/SAPI.c) ==> SG SAPI模块的环境变量,主要是包括每次PHP请求的数据
  • zend_compiler_globals compiler_globals(Zend/zend_compile.c) ==> CG Zend engine 编译过程需要的全局变量
  • zend_executor_globals executor_globals(Zend/zend_compile.c) ==> EG Zend engine 执行过程中需要的全局变量
  • zend_alloc_globals alloc_globals(Zend/zend_alloc.c) ==> AG Zend engine memory management globals
  • zend_gc_globals gc_globals(Zend/zend_gc.c) ==> GC_G Zend engine gc related globals
  • module globals(用Zend/zend_API.h中的DECLARE宏定义在相应模块中) ==> PHP扩展模块的全局变量

以上几个全局变量基本是从PHP环境到SAPI环境到Zend engine编译执行以及我们写自己的扩展时会涉及到的。


3.sapi

sapi模块主要是提供一套外界使用zend engine的统一接口,提供不同的服务模式,比如典型的几个模式:

  • cli
  • cgi
  • apache module

不同的服务模式在模块的初始化,请求的初始化不太相同,对于服务类的通常只需要初始化一次sapi模块,sapi_startup–>sapi_module.startup
包括上述全局变量/PHP扩展模块初始化/Zend扩展的初始化等,之后只需要针对每次请求调用php_request_startup,zend_activate,sapi_activate,来激活request,sapi,zend engine,重新设置请求的数据,响应请求。


4.startup process

基本调用流程:
//初次调用流程

  • sapi_startup(&sapi_module)
  • sapi_module.startup()
    • php_module_startup()
    • sapi_activate()
    • gc_global_ctor()
    • zend_startup()
      • zend_mm_startup()
    • sapi_deactivate()

//请求流程

  • php_request_startup()
    • zend_activate()
    • init_gc()
    • init_compiler()
    • init_executor()
    • sapi_activate()
  • php_request_shutdown()
    • zend_deactivate()
    • sapi_deactivate()
    • or full zend_memory_shutdown
    • or sapi_module.shutdown

5.memory manager

(1)内存管理相关的重要数据结构

  • zend_mm_heap
  • zemd_mm_storage
  • zend_mm_chunck
  • zend_mm_page
  • zend_mm_page_map
  • zend_mm_bin
  • zend_arena
  • zend_mm_huge_list
  • zend_mm_free_slot

(2)sapi模块第一次初始化时:

  • zend_mm_startup
    • alloc_globals_ctor
    • zend_mm_init初始化zend_mm_heap,分配main_chunck,并初始化main_chunck中的zend_mm_heap结构体,
      main_chunck负责存储相关信息,只有main_chunck使用了heap结构体,并将heap与AG(mm_heap)挂接

(3)每次请求init_compiler时分配zend_memory_arena

  • init_compiler
    • zend_arena_create(64M) 放入CG(arena)
    • emalloc
    • _emalloc
      • zend_mm_alloc_heap(AG(mm_heap)…)
      • < 3072字节 zend_mm_alloc_small
        • 根据size计算free_slots中是否还有空的小块item,如果有直接返回指针,否则zend_mm_alloc_small_slow
        • zend_mm_alloc_pages根据bin_pages数组得到需要分配的页面,
          如果空闲页面不足则重新zend_mm_chunck_alloc(mmap)分配chunck
      • < 2M-4096字节 zend_mm_alloc_large
        • 直接使用zend_mm_alloc_pages分配
      • zend_mm_alloc_huge
        • 使用zend_mm_chunck_alloc,加入heap的hugeblock_list

6.compiler and executor

(1)编译接口及编译流程:

  • zend_eval_string(zend_execute_API.c)
    • zend_eval_stringl
    • zend_compile_string(zend_compile.c)
      • compile_string(zend_language_scanner.c)
      • zendparse(就是yyparse)(zend_language_parse.y) ==> 通过parser调用lexer,生成抽象语法树ast_list,存到CG(ast)
      • zend_compile_top_stmt ==> 编译ast生成oparray
      • pass_two(oparray) ==> 优化?

(2)执行流程

  • zend_execute(zend_vm_execute.h)
    • zend_vm_stack_push_call_frame
    • i_init_execute_data
    • zend_execute_ex
    • execute_ex(zend_vm_execute.h)
    • zend_vm_stack_free_call_frame

后续部分:gc/php modules and zend extensions/grammar/ast/thread safety

ref:php-src

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享:
开发与运维
使用钉钉扫一扫加入圈子
+ 订阅

集结各类场景实战经验,助你开发运维畅行无忧

其他文章