ã³ã¬ã»ãã«ããã³æåã®éšåã§ã¯ãPHP 5ãšPHP 7ã®éã®å€ã®å
éšè¡šçŸã®é«ã¬ãã«ã®éãã調ã¹ãŸãããèŠããŠããããã«ãäž»ãªéãã¯
zval
åå¥ã«å²ãåœãŠããããrefcountãããèªäœã«ä¿åããªãããšã§ãã æŽæ°ãæµ®åå°æ°ç¹ãªã©ã®åçŽãªå€ã¯
zval
ã«çŽæ¥æ ŒçŽã§ããŸãããè€éãªå€ã¯å¥ã®æ§é äœãžã®ãã€ã³ã¿ãŒã䜿çšããŠè¡šãããŸãã
ãããã®è¿œå ã®æ§é ã¯ãã¹ãŠã
zend_refcounted
å®çŸ©ãããæšæºããããŒã䜿çšã
zend_refcounted
ã
struct _zend_refcounted { uint32_t refcount; union { struct { ZEND_ENDIAN_LOHI_3( zend_uchar type, zend_uchar flags, uint16_t gc_info) } v; uint32_t type_info; } u; };
ãã®ããããŒã«ã¯ã
refcount
ãããŒã¿åã
gc_info
ã¬ããŒãž
gc_info
æ
å ±ãããã³åäŸå
flags
ã»ã«ãå«ãŸããŠããŸãã æ¬¡ã«ãåã
ã®è€ååãæ€èšããããããPHP 5ã§ã®å®è£
ãšæ¯èŒããŸããç¹ã«ãèšäºã®ååã§ãã§ã«èª¬æãããªã³ã¯ã«ã€ããŠèª¬æããŸãã ããã§æ€èšããã®ã«ååã«è峿·±ããšã¯èããŠããªãããããªãœãŒã¹ã«ã€ããŠã¯è§ŠããŸããã
è¡
PHP 7ã§ã¯ãæååã¯
zend_string
ã¿ã€ãã䜿çšããŠè¡šãããŸãã
struct _zend_string { zend_refcounted gc; zend_ulong h; size_t len; char val[1]; };
refcounted
ããããŒã«å ããŠãããã·ã¥ãã£ãã·ã¥hã
len
lengthãããã³
val
ã䜿çšããŸãã ããã·ã¥ãã£ãã·ã¥ã¯ã
HashTable
ãã
HashTable
æååã®ããã·ã¥ãåèšç®ããªãããã«äœ¿çšãã
HashTable
ã æåã®äœ¿çšæã«ã¯ããŒã以å€ã®ããã·ã¥ãšããŠåæåãããŸãã
Cã®ããŸããŸãªããã¯ã«ç²ŸéããŠããªãå Žåã
val
ã®å®çŸ©ã¯å¥åŠã«æãããããããŸãããåäžã®èŠçŽ ãæã€æåã®é
åãšããŠå®£èšãããŸãã ããããæååã1æåããé·ãä¿åãããã®ã¯ç¢ºãã§ãã ããã§ã¯ããæ§é çããã¯ããšåŒã°ããã¡ãœããã䜿çšããŸããé
åã¯1ã€ã®èŠçŽ ã§å®£èšãããŸããã
zend_string
äœæãããšãã«ãããé·ãæååãæ ŒçŽããå¯èœæ§ã倿ããŸãã ããã«ã
val
ã䜿çšããŠããé·ãæååã«ã¢ã¯ã»ã¹ã§ããŸãã
æè¡çã«ã¯ãããã¯æé»çãªæ©èœã§ãã1æåã®é
åãèªã¿æžãããããã§ãã ãã ããCã³ã³ãã€ã©ã¯äœãäœã§ããããçè§£ããã³ãŒããæ£åžžã«åŠçããŸãã C99ã¯ãã®æ©èœããåçé
åã®ã¡ã³ããŒããšããŠãµããŒãããŸãããMicrosoftã®å人ã®ãããã§ãC99ã¯ã¯ãã¹ãã©ãããã©ãŒã äºææ§ãå¿
èŠãšããéçºè
ã䜿çšã§ããŸããã
æåå倿°ã®æ°ããå®è£
ã«ã¯ãCèšèªã®éåžžã®æååã«æ¯ã¹ãŠããã€ãã®å©ç¹ããããŸãããŸããè¿ãã®ã©ããã«ããã³ã°ãããªãé·ããçµ±åããŸããã 第äºã«ãã¿ã€ãã«ã¯åç
§ã«ãŠã³ãã䜿çšããããã
zval
ã䜿çšããã«ããŸããŸãªå Žæã§æååã䜿çšã§ããããã«ãªã
zval
ã ããã¯ãããã·ã¥ããŒãã«ã®ããŒãå
±æããããã«ç¹ã«éèŠã§ãã
ããããè»èã«ã¯å€§ããªããšããããŸãã
zend_string
ããCèšèªã®æååã
zend_string
ç°¡åã§ããïŒstr-> valã䜿çšïŒãCã®æååãã
zend_string
ãçŽæ¥ååŸããããšã¯ã§ããŸããã ãããè¡ãã«ã¯ãæååå€ãæ°ããäœæããzend_stringã«ã³ããŒããå¿
èŠããããŸãã ããã¹ãæååïŒãªãã©ã«æååïŒãã€ãŸãCãœãŒã¹ã³ãŒãã«ãã宿°æååãæäœããå Žåãç¹ã«é¢åã§ãã
æååã«ã¯ã察å¿ããGCãã£ãŒã«ãã«ããŸããŸãªãã©ã°ãæ ŒçŽã§ããŸãã
æ°žç¶çãªæååã¯ãZendã¡ã¢ãªãããŒãžã£ãŒïŒZMMïŒã®ä»£ããã«éåžžã®ã·ã¹ãã ã¢ãã±ãŒã¿ãŒã䜿çšããããã1ã€ã®ãªã¯ãšã¹ããããé·ãååšã§ããŸãã äœ¿çšæžã¿ã®ãã£ã¹ãã³ãµãŒããã©ã°ãšããŠäœ¿çšããå Žåã
zval
æ°žç¶æååãééçã«äœ¿çšã§ããŸãã PHP 5ã§ã¯ãäºåã«ZMMã«ã³ããŒããå¿
èŠããããŸããã
åé¢ïŒã€ã³ã¿ãŒã³ïŒæååã¯ãèŠæ±ãå®äºããåã«ç Žæ£ãããªãæååã§ãããããåç
§ã«ãŠã³ã¿ãŒã䜿çšããå¿
èŠã¯ãããŸããã ãããã¯éè€æé€ãããŠãããããæ°ããå颿ååãäœæãããšãã«ããšã³ãžã³ã¯æåã«åãå€ãæã€å¥ã®æååããããã©ããã確èªããŸãã äžè¬ã«ãPHPã³ãŒãã§äœ¿çšå¯èœãªãã¹ãŠã®è¡ïŒå€æ°ã颿°åãªã©ãå«ãïŒã¯éåžžåé¢ãããŠããŸãã äžå€æååã¯ãã¯ãšãªã®éå§åã«äœæãããå颿ååã§ãã éé¢ããããã®ãšã¯ç°ãªãããªã¯ãšã¹ãã®æåŸã§ç Žæ£ãããããšã¯ãããŸããã
OPCacheã䜿çšãããå Žåãåé¢ãããè¡ã¯å
±æã¡ã¢ãªïŒSHMïŒã«æ ŒçŽããããã¹ãŠã®PHPããã»ã¹ã§äœ¿çšãããŸãã ãã®å Žåãåé¢ãããæååã¯ãšã«ããç Žå£ãããªããããäžå€ã®æååã¯åœ¹ã«ç«ããªããªããŸãã
é
å
é
åã®æ°ããå®è£
ã«é¢ãã詳现ã¯èª¬æããŸããã äžå€é
åã®ã¿ã«èšåããŸãã ããã¯ãå€ç«ããç·ã®äžçš®ã§ãã ãŸããåç
§ã«ãŠã³ã¿ãŒã䜿çšãããèŠæ±ãçµäºãããŸã§ç Žæ£ãããŸããã ããã€ãã®ã¡ã¢ãªç®¡çæ©èœã«ãããäžå€é
åã¯OPCacheã®å®è¡äžã«ã®ã¿äœ¿çšãããŸãã ãããäžãããã®ã¯ãäŸããèŠãããŸãïŒ
for ($i = 0; $i < 1000000; ++$i) { $array[] = ['foo']; } var_dump(memory_get_usage());
OPCacheãæå¹ã«ãããšã32 MBã®ã¡ã¢ãªã䜿çšããããããªãã§äœ¿çšãããŸã-ãã®å Žåã
$array
åèŠçŽ ã¯æ°ããã³ããŒ
['foo']
ååŸããããã390åãŸã§ã§ãã åç
§ã«ãŠã³ã¿ãŒãå¢ãã代ããã«ã³ããŒãäœæãããã®ã¯ãªãã§ããïŒ å®éãVMæååãªãã©ã³ãã¯ãSHMã«éåããªãããã«åç
§ã«ãŠã³ã¿ãŒã䜿çšããŸããã å°æ¥ããã®å£æ»
çãªç¶æ³ãä¿®æ£ãããOPCacheãæŸæ£ãããããšãé¡ã£ãŠããŸãã
PHP 5ã®ãªããžã§ã¯ã
PHP 7ã§ã®ãªããžã§ã¯ãã®å®è£
ã«ã€ããŠèª¬æããåã«ãPHP 5ã§ãªããžã§ã¯ããã©ã®ããã«é
眮ãããã©ã®ãããªãã¡ãªããããã£ãã®ããæãåºããŸãããã
zval
ãæ¬¡ã®ããã«å®çŸ©ããã
zend_object_value
æ ŒçŽ
zval
䜿çšãããŸããã
typedef struct _zend_object_value { zend_object_handle handle; const zend_object_handlers *handlers; } zend_object_value;
handle
ããŒã¿ã®æ€çŽ¢ã«äœ¿çšãããäžæã®ãªããžã§ã¯ãIDã
handlers
ã¯ããªããžã§ã¯ãã®ããŸããŸãªåäœãå®è£
ããVTable颿°ãã€ã³ã¿ãŒã§ãã ãéåžžã®ããªããžã§ã¯ãã®å Žåããã®ãã³ãã©ãŒããŒãã«ã¯åãã«ãªããŸãã ããããPHPæ¡åŒµæ©èœã«ãã£ãŠäœæããããªããžã§ã¯ãã¯ããªããžã§ã¯ãã®åäœã倿Žãããã³ãã©ãŒã®ã«ã¹ã¿ã ã»ããã䜿çšã§ããŸãïŒããšãã°ãæŒç®åã®ãªãŒããŒã©ã€ãïŒã
ãªããžã§ã¯ãèå¥åã¯ãããªããžã§ã¯ãã¹ãã¢ãã®ã€ã³ããã¯ã¹ãšããŠäœ¿çšãããŸãã ããã¯é
åã§ãïŒ
typedef struct _zend_object_store_bucket { zend_bool destructor_called; zend_bool valid; zend_uchar apply_count; union _store_bucket { struct _store_object { void *object; zend_objects_store_dtor_t dtor; zend_objects_free_object_storage_t free_storage; zend_objects_store_clone_t clone; const zend_object_handlers *handlers; zend_uint refcount; gc_root_buffer *buffered; } obj; struct { int next; } free_list; } bucket; } zend_object_store_bucket;
è峿·±ãããšããããããããŸãã æåã®3ã€ã®èŠçŽ ã¯ãäœããã®ã¡ã¿ããŒã¿ã§ãïŒãªããžã§ã¯ãã®ãã¹ãã©ã¯ã¿ãåŒã³åºããããã©ããããã®ãã±ããã䜿çšããããã©ãããååž°ã¢ã«ãŽãªãºã ããã®ãªããžã§ã¯ãã«ã¢ã¯ã»ã¹ããåæ°ïŒã
union
èšèšã¯ãã¹ãã¬ãŒãžãçŸåšäœ¿çšäžãã空ãã¹ãã¬ãŒãžã®ãªã¹ãã«ãããã«ãã£ãŠç°ãªããŸãã
struct_store_object
䜿çšããå Žåã¯éèŠã§ãã
object
ã¯ç¹å®ã®ãªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã§ãã ãªããžã§ã¯ãã®ãµã€ãºã¯åºå®ãããŠããªãããããªããžã§ã¯ãã¹ãã¢ã«ã¯çµ±åãããŸããã ãã€ã³ã¿ãŒã®åŸã«ãç Žå£ãè§£æŸãããã³è€è£œãè¡ã3ã€ã®ãã³ãã©ãŒãç¶ããŸãã PHPã§ã¯ããªããžã§ã¯ãã®ç Žæ£ãšè§£æŸã®æäœã¯æç€ºçãªããã·ãŒãžã£ã§ãããæåã®ãªããžã§ã¯ãã¯ã¹ããããããå ŽåããããŸãïŒã¯ãªãŒã³ã·ã£ããããŠã³ïŒã ã¯ããŒã³äœæãã³ãã©ãŒã¯äºå®äžãŸã£ãã䜿çšãããŠããŸããã ãããã®ã¹ãã¬ãŒãžãã³ãã©ã¯ãå
±æã§ã¯ãªãéåžžã®ãªããžã§ã¯ããã³ãã©ã§ã¯ãªãããããªããžã§ã¯ãããšã«è€è£œãããŸãã
ãããã®ãã€ã³ã¿ãŒãã³ãã©ãŒã¯ãéåžžã®ãã³ãã©ãŒã«ç§»åã
handlers
ã ãªããžã§ã¯ãããã®
zval
éç¥ãªãã«ç Žæ£ãããå Žåããããã¯ä¿åãããŸãïŒéåžžã¯ãã³ãã©ãŒãæ ŒçŽãããŸãïŒã
ãªããžããªã«ã¯
refcount
ãå«ãŸã
refcount
ãããã¯ãPHP 5ã§ã¯åç
§ã«ãŠã³ãããã§ã«
zval
æ ŒçŽãããŠãããšããäºå®ã«ç
§ãããŠç¹å®ã®å©ç¹ãæäŸã
zval
ã ãªã2ã€ã®ã«ãŠã³ã¿ãŒãå¿
èŠãªã®ã§ããïŒ éåžžã
zval
ãåçŽãªã«ãŠã³ã¿ãŒã®å¢å ã«ãã£ãŠãã³ããŒããããŸãã ããããå®å
šãªã³ããŒã衚瀺ãããããšããããŸããã€ãŸããåã
zend_object_value
ã«å¯ŸããŠããŸã£ããæ°ãã
zval
ãŸãã ãã®çµæã2ã€ã®ç°ãªã
zval
ãåããªããžã§ã¯ãã¹ãã¬ãŒãžã䜿çšãããããåç
§ã«ãŠã³ããå¿
èŠã«ãªããŸãã ãã®ãäºéã«ãŠã³ããã¯ãPHP 5ã®
zval
å®è£
ã®ç¹åŸŽçãªæ©èœã§ããåãçç±ã§ãGCã«ãŒããããã¡ãŒå
ã®ãããã¡ãŒãã€ã³ã¿ãŒãè€è£œãããŸãã
ãªããžã§ã¯ãã¹ãã¢ã«ãã£ãŠåç
§ããã
object
æ€èšã
object
ã ãŠãŒã¶ãŒç©ºéã®éåžžã®ãªããžã§ã¯ãã¯æ¬¡ã®ããã«å®çŸ©ãããŸãã
typedef struct _zend_object { zend_class_entry *ce; HashTable *properties; zval **properties_table; HashTable *guards; } zend_object;
zend_class_entry
ã¯ããšã³ãã£ãã£ããªããžã§ã¯ãã§ããã¯ã©ã¹ãžã®ãã€ã³ã¿ã§ãã æ¬¡ã®2ã€ã®èŠçŽ ã¯ã2ã€ã®ç°ãªãæ¹æ³ã§ãªããžã§ã¯ãããããã£ã®ã¹ãã¬ãŒãžãæäŸããããã«äœ¿çšãããŸãã åçããããã£ïŒã€ãŸããå®è¡æã«è¿œå ãããã¯ã©ã¹ã§å®£èšãããŠããªãããããã£ïŒã®å Žåãããããã£ã®ååãšãã®å€ããªã³ã¯ããããããã£ããã·ã¥ããŒãã«ã䜿çšãããŸãã
宣èšãããããããã£ã®å Žåãæé©åã䜿çšãããŸãã ã³ã³ãã€ã«äžã«ãé¡äŒŒã®åããããã£ãã€ã³ããã¯ã¹ã«æžã蟌ãŸãããã®å€ã
properties_table
ã®ã€ã³ããã¯ã¹ã«ä¿åãã
properties_table
ã ååãšã€ã³ããã¯ã¹ã®é¢é£ä»ãã¯ãã¯ã©ã¹ãšã³ããªã®ããã·ã¥ããŒãã«ã«æ ŒçŽãããŸãã ãããã£ãŠãåã
ã®ãªããžã§ã¯ãã«ã€ããŠã¯ãããã·ã¥ããŒãã«ã¡ã¢ãªãéå°ã«äœ¿çšãããŸãã ããã«ãããããã£ã€ã³ããã¯ã¹ã¯å®è¡æã«å€æ
çã«ãã£ãã·ã¥ãããŸãã
guards
ããã·ã¥ããŒãã«ã¯ã
_get
ãããªãããžãã¯ãã¡ãœããã®ååž°çãªåäœãå®è£
ããããã«äœ¿çšãããŸãããããã§ã¯èæ
®ããŸããã
åè¿°ã®äºéåç
§ã«ãŠã³ãã«å ããŠããªããžã§ã¯ãã®è¡šçŸã«ã¯å€§éã®ã¡ã¢ãªãå¿
èŠã§ãã 1ã€ã®ããããã£ãæã€æå°ãªããžã§ã¯ãã¯136ãã€ãïŒzvalãã«ãŠã³ãããªãïŒããããŸãã ããã«ãå€ãã®éæ¥ã¢ãã¬ã¹ã䜿çšãããŸãã ããšãã°ã
zval
ãªããžã§ã¯ãããããããã£ãåŒã³åºãã«ã¯ãæåã«ãªããžã§ã¯ãã¹ãã¢ã次ã«Zendãªããžã§ã¯ããããããã£ããŒãã«ãæåŸã«
zval
ã«ãã£ãŠåç
§ãããããããã£ã
zval
ãŸãã å°ãªããšã4ã¬ãã«ã®éæ¥ã¢ãã¬ã¹æå®ãããã³å®éã®ãããžã§ã¯ãã§ã¯å°ãªããšã7ã¬ãã«ã«ãªããŸãã
PHP 7ã®ãªããžã§ã¯ã
圌ãã¯ã第7ããŒãžã§ã³ã§äžèšã®ãã¹ãŠã®æ¬ ç¹ãä¿®æ£ããããšããŸããã ç¹ã«ããªã³ã¯ã®äºéã«ãŠã³ããæåŠããã¡ã¢ãªæ¶è²»éãšéæ¥ã¢ãã¬ã¹æå®ã®éãåæžããŸããã ããã¯ãæ°ãã
zend_object
æ§é ã®
zend_object
ã§ãã
struct _zend_object { zend_refcounted gc; uint32_t handle; zend_class_entry *ce; const zend_object_handlers *handlers; HashTable *properties; zval properties_table[1]; };
ãã®æ§é ã¯ããªããžã§ã¯ãã®æ®ãã®ã»ãšãã©ãã¹ãŠã§ãã
zend_object_value
ã¯ããªããžã§ã¯ãããã³ãªããžã§ã¯ãã¹ãã¬ãŒãžãžã®çŽæ¥ãã€ã³ã¿ã«çœ®ãæããããŸãããå®å
šã«é€å€ãããŠããããã§ã¯ãããŸããããããã»ã©é »ç¹ã«ééããããšã¯ãããŸããã
åŸæ¥ã®
zend_refcounted
ããããŒã«å ããŠã
handle
ãš
handlers
ã¯
handlers
å
ã§ãç§»åãã
handlers
ã
properties_table
ã¯æ§é ããã¯ã䜿çšããããã«ãªã£ãããã
zend_object
ãšããããã£ããŒãã«ã¯1ã€ã®ãããã¯ã«é
眮ãããŸãã ãããŠãã¡ããã
zval
èªäœã¯ããããžã®ãã€ã³ã¿ã§ã¯ãªããããããã£ããŒãã«ã«çŽæ¥å«ãŸããããã«ãªããŸããã
ãªããžã§ã¯ãã
__get
ãªã©ã䜿çšããå Žåã
guards
ããŒãã«ã¯ãªããžã§ã¯ãæ§é ããåé€ãããæåã®
properties_table
ã»ã«ã«æ ŒçŽãããŸãã ãããã®ãããžãã¯ãã¡ãœããã䜿çšãããªãå Žåã
guards
ããŒãã«ã¯é¢ä¿ããŸããã
以åã«ãªããžã§ã¯ãã¹ãã¢ã«ä¿åãããŠãã
dtor
ã
free_storage
ããã³
clone
ãã³ãã©ãŒã¯ã
handlers
ããŒãã«ã«ç§»åããŸããã
struct _zend_object_handlers { int offset; zend_object_free_obj_t free_obj; zend_object_dtor_obj_t dtor_obj; zend_object_clone_obj_t clone_obj;
offsetèŠçŽ ã¯ããã³ãã©ãŒã§ã¯ãããŸããã ãªããžã§ã¯ãã®è¡šçŸæ¹æ³ã«é¢ä¿ããŸããå
éšãªããžã§ã¯ãã¯åžžã«æšæºã®
zend_object
å®è£
ããŸãããåæã«ãäžãããäžå®æ°ã®èŠçŽ ã远å ããŸãã PHP 5ã§ã¯ãæšæºãªããžã§ã¯ãã®åŸã«è¿œå ãããŸããã
struct custom_object { zend_object std; uint32_t something;
ã€ãŸãã
zend_object*
ãã«ã¹ã¿ã
struct custom_object*
éä¿¡ããã ãã§ãã ããã¯ãCã§ã®æ§é ã®ç¶æ¿ã®å°å
¥ã瀺åããŠããŸããããããPHP 7ã®ã¢ãããŒãã«ã¯ç¬èªã®ç¹æ§ããããŸãã ãããã£ãŠã7çªç®ã®ããŒãžã§ã³ã§ã¯ã远å ã®ã¡ãœãããæšæºãªããžã§ã¯ãã®
åã«ä¿åãããŸãã
struct custom_object { uint32_t something;
ããã«ããã
offset
ãéã«ãããããåçŽãªå€æã䜿çšããŠ
zend_object*
ãš
struct custom_object*
éãçŽæ¥å€æããããšãã§ããªããªããŸãã ãªããžã§ã¯ããã³ãã©ããŒãã«ã®æåã®èŠçŽ ã«æ ŒçŽãããŸãã ã³ã³ãã€ã«æã«ã
offsetof()
ãã¯ãã䜿çšããŠ
offset
ãæ±ºå®ã§ããŸãã
ãªãPHP 7ã«ãŸã
handle
ãå«ãŸããŠããã®ãçåã«æãããã§ãããã çµå±ã®ãšããã
zend_object
ãžã®çŽæ¥ãã€ã³ã¿ãŒã䜿çšãããããã«ãªã£ãããããªããžããªå
ã®ãªããžã§ã¯ããæ€çŽ¢ããããã«
handle
ã䜿çšããå¿
èŠããªããªããŸããã ãã ããå®è³ªçã«åãæšãŠããã圢åŒã§ã¯ãããŸããããªããžã§ã¯ãã®ãªããžããªãããããã
handle
ãå¿
èŠã§ãã ããã¯ããªããžã§ã¯ããžã®ãã€ã³ã¿ãŒã®åçŽãªé
åã§ãã ãªããžã§ã¯ããäœæãããšããã€ã³ã¿ãŒã¯
handle
ã€ã³ããã¯ã¹å
ã®ã¹ãã¢ã«é
眮ããããªããžã§ã¯ããè§£æŸããããšããããåé€ãããŸãã
ãªããžã§ã¯ãã¹ãã¬ãŒãžã«ã¯ä»ã«äœãå¿
èŠã§ããïŒ ãªã¯ãšã¹ãã®å®äºæã«ããšã°ãŒãã¥ãŒã¿ããã§ã«éšåçã«åäœã忢ããŠããããããŠãŒã¶ãŒã³ãŒãã®å®è¡ãå®å
šã§ãªãå ŽåããããŸãã ãã®ç¶æ³ãåé¿ããããã«ãPHPã¯ãã¹ãŠã®ãªããžã§ã¯ããã¹ãã©ã¯ã¿ãŒãå®äºã®åææ®µéã§éå§ããŸãã ãã®ããã«ã¯ããã¹ãŠã®ã¢ã¯ãã£ããªãªããžã§ã¯ãã®ãªã¹ããå¿
èŠã§ãã
ããã«ããã³ãã«ã¯åãªããžã§ã¯ãã«äžæã®IDãä»äžããããããããã°ã«åœ¹ç«ã¡ãŸãã ããã«ããã2ã€ã®ãªããžã§ã¯ããåããã©ãããããã«çè§£ã§ããŸãã ãªããžã§ã¯ããã³ãã©ã¯ãªããžã§ã¯ãã®ãªããžããªã§ã¯ãããŸããããHHVMã«ä¿åããããŸãŸã§ãã
PHP 5ãšã¯ç°ãªãã1ã€ã®åç
§ã«ãŠã³ã¿ãŒã®ã¿ã䜿çšãããããã«ãªããŸããïŒ
zval
ã§ã¯ãªããªããŸããïŒã ã¡ã¢ãªæ¶è²»éã倧å¹
ã«æžå°ããŸãããããŒã¹ãªããžã§ã¯ãã«ã¯40ãã€ãã
zval
ãå«ã宣èšãããããããã£ããšã«16ãã€ãã§
zval
ã§ãã å€ãã®äžéæ§é ãé€å€ãããããä»ã®æ§é ãšããŒãžãããããã鿥ã¢ãã¬ã¹æå®ã¯ã¯ããã«å°ãªããªããŸãã ãããã£ãŠãããããã£ãèªã¿åããšãã«ã4ã€ã§ã¯ãªã1ã€ã®ã¬ãã«ã®éæ¥ã¢ãã¬ã¹æå®ã®ã¿ã䜿çšãããããã«ãªããŸããã
鿥zval
ç¹å¥ãªå Žåã«äœ¿çšãããç¹å¥ãª
zval
åãèŠãŠã¿ãŸãããã ãããã®1ã€ã¯
IS_INDIRECT
ã§ãã 鿥
zval
ã®å€ã¯å¥ã®å Žæã«ä¿åãããŸãã ãã®
zval
ã¿ã€ãã¯ã
zval
åã蟌ãŸããŠãã
zend_reference
æ§é ãšã¯å¯Ÿç
§çã«ãå¥ã®
zval
çŽæ¥æããšããç¹ã§
IS_REFERENCE
ãšç°ãªããŸãã
ãã®ã¿ã€ãã®
zval
䟿å©ã«ãªããŸããïŒ ãŸããPHPã§ã®å€æ°ã®å®è£
ãèŠãŠã¿ãŸãããã ã³ã³ãã€ã«æ®µéã§èªèãããŠãããã¹ãŠã®å€æ°ã¯ã€ã³ããã¯ã¹ã«å
¥åããããã®å€ã¯ãã®ã€ã³ããã¯ã¹ã®ã³ã³ãã€ã«æžã¿å€æ°ã®ããŒãã«ïŒCVïŒã«æžã蟌ãŸããŸãã ããããPHPã§ã¯ã倿°å€æ°ã䜿çšããŠããŸãã¯ã°ããŒãã«ã¹ã³ãŒãã«ããå Žåã¯
$GLOBALS
ã䜿çšããŠã倿°ãåçã«åç
§ããããšãã§ããŸãã ãã®ã¢ã¯ã»ã¹ã«ãããPHPã¯å€æ°åãšãã®å€ã®ããããå«ã颿°/ã¹ã¯ãªããã®ã·ã³ãã«ããŒãã«ãäœæããŸãã
åé¡ã¯ã2çš®é¡ã®ã¢ã¯ã»ã¹ãåæã«ãµããŒãããæ¹æ³ã§ãã éåžžã®å€æ°ãåŒã³åºãã«ã¯ãCVããŒãã«ã䜿çšããŠã¢ã¯ã»ã¹ããå¿
èŠãããã倿°å€æ°ã«ã€ããŠã¯ãã·ã³ãã«ããŒãã«ã䜿çšããŠã¢ã¯ã»ã¹ããå¿
èŠããããŸãã PHP 5ã§ã¯ãCVããŒãã«ã¯äºé鿥
zval**
ãã€ã³ã¿ãŒã䜿çšããŠããŸããã éåžžã®ç¶æ³ã§ã¯ããããã®ãã€ã³ã¿ãŒã¯ãã€ã³ã¿ãŒ
zval*
2çªç®ã®ããŒãã«ã«
zval*
ãããã
zval
åç
§ã
zval
ã
+------ CV_ptr_ptr[0] | +---- CV_ptr_ptr[1] | | +-- CV_ptr_ptr[2] | | | | | +-> CV_ptr[0] --> some zval | +---> CV_ptr[1] --> some zval +-----> CV_ptr[2] --> some zval
çŸåšãã·ã³ãã«ããŒãã«ã䜿çšããŠãããããåäžã®
zval*
ãã€ã³ã¿ãŒãæã€2çªç®ã®ããŒãã«ã¯é©çšã§ããªããªãã
zval**
ãã€ã³ã¿ãŒã¯ããã·ã¥ããŒãã«ã¹ãã¢ãåç
§ããŸãã 3ã€ã®å€æ°$ aã$ bããã³$ cã®å°ããªå³ïŒ
CV_ptr_ptr[0] --> SymbolTable["a"].pDataPtr --> some zval CV_ptr_ptr[1] --> SymbolTable["b"].pDataPtr --> some zval CV_ptr_ptr[2] --> SymbolTable["c"].pDataPtr --> some zval
PHP 7ã§ã¯ãããã·ã¥ããŒãã«ã®ãµã€ãºã倿Žããããšãªããžããªãžã®ãã€ã³ã¿ãŒãç¡å¹ã«ãªãããããã®æ¹æ³ã¯äœ¿çšã§ããªããªããŸããã çŸåšããã®ã¢ãããŒãã䜿çšãããŠããŸããCVããŒãã«ã«æ ŒçŽãããŠãã倿°ã®å Žåãæåã®ããã·ã¥ããŒãã«ã«ã¯CVã¬ã³ãŒããæãINDIRECTã¬ã³ãŒããå«ãŸããŠããŸãã ã·ã³ãã«ããŒãã«ãååšããéããCVããŒãã«ã¯åé
åžãããŸããã ãããã£ãŠãç¡å¹ãªãã€ã³ã¿ãŒã®åé¡ã¯ãããããŸããã
CV $ aã$ bã$ cãããã³åçã«äœæããã倿°$ dãæã€é¢æ°ã䜿çšãããšãã·ã³ãã«ããŒãã«ã¯æ¬¡ã®ããã«ãªããŸãã
SymbolTable["a"].value = INDIRECT --> CV[0] = LONG 42 SymbolTable["b"].value = INDIRECT --> CV[1] = DOUBLE 42.0 SymbolTable["c"].value = INDIRECT --> CV[2] = STRING --> zend_string("42") SymbolTable["d"].value = ARRAY --> zend_array([4, 2])
鿥
zval
ã¯ã
zval IS_UNDEF
æãããšãã§ããŸãã ãã®å Žåãããã·ã¥ããŒãã«ã«é¢é£ããããŒãå«ãŸããŠããªããã®ããã«æ±ãããŸãã ãŸãã
unset($a)
ã§
UNDEF
ã¿ã€ãã
CV[0]
ã«æžã蟌ããšãæåããŒãã«ã«ããŒãaãããªãããã«åŠçãããŸãã
宿°ãšAST
æåŸã«ãPHP 5ããã³7ã§å©çšå¯èœãª2ã€ã®ç¹å¥ãª
zval
ã¿ã€ã
IS_CONSTANT
ããã³
IS_CONSTANT_AST
ãŸãã ãããã®ç®çãçè§£ããããã«ãäŸãèããŠã¿ãŸãããã
function test($a = ANSWER, $b = ANSWER * ANSWER) { return $a + $b; } define('ANSWER', 42); var_dump(test());
ããã©ã«ãã§ã¯ãANSWER宿°ã¯
test()
颿°ã®ãã©ã¡ãŒã¿ãŒå€ã«äœ¿çšãããŸãã ãã ãã颿°ã宣èšãããæç¹ã§ã¯ãŸã å®çŸ©ãããŠããŸããã 宿°ã®å€ã¯ã
define()
åŒã³åºããåŸã«ã®ã¿ç¥ãããããã«ãªã
define()
ã ãããã£ãŠããã©ã¡ãŒã¿ãŒãšããããã£ã®æ¢å®å€ãããã³å®æ°ãšãéçåŒããåãå
¥ããããšãã§ãããã¹ãŠã®èŠçŽ ã¯ãæåã®äœ¿çšãŸã§åŒã®èšç®ãé
ãããããšãã§ããŸãã
å€ã宿°ïŒãŸãã¯ã¯ã©ã¹å®æ°ïŒã®å Žåã
zval
åã®
IS_CONSTANT
宿°ã®ååãšãšãã«
IS_CONSTANT
ããŸãã å€ãåŒã®å Žåãæœè±¡æ§æããªãŒïŒASTïŒãåç
§ããŠãã¿ã€ã
IS_CONSTANT_AST
ãŸãã
* * *
ããã§ãPHP 7ã§ã®å€ã®è¡šçŸã«é¢ãããã®é·ãæŠèŠãç· ãããããŸãããã