SlideShare ist ein Scribd-Unternehmen logo
1 von 31
1
PHP's Virtual Machine
2
Hello
● Julien PAULI
● Programming in PHP since early 2000s
● PHP Internals hacker and trainer
● PHP 5.5/5.6 Release Manager
● Working at SensioLabs in Paris - Blackfire
● Writing PHP tech articles and books
● http://phpinternalsbook.com
● @julienpauli - github.com/jpauli - jpauli@php.net
● Like working on OSS such as PHP :-)
3
PHP
● A program in itself
● Written in C
● Goal : Define a programming Web language
● High level, interpreted
● Interpreted language
● Less efficient than native-instr compiled language
● but simpler to handle
4
PHP
5
PHP from inside
● A software virtual machine
● Compiler/Executor
● intermediate OPCode
● Mono Thread, Mono process
● Automatic dynamic memory management
● Memory Manager
● Garbage collector
6
Zend Engine
● The heart of PHP
● An extensible part
● extensions and zend_extensions can change it
● A Virtual Machine
● A compiler
● An executor
● Some utilities
● OPCache
● A Zend extension that plays with the engine deeply
● Compiler optimizer is stored into OPCache
7
Request treatment steps
● Startup (memory allocations)
● Compilation
● Lexical and syntaxic analysis
● Compilation (OP Code generation)
● Execution
● OPCode interpretation
● Several VM flavors
● Include/require/eval = go back to compilation
● Shutdown (free resources)
● "Share nothing architecture"
Startup
Shutdown
zend_compile_file()
zend_execute()
8
Script execution
● Compilation
● Optmization (OPCache)
● Execution
● Destruction
9
Lexical analysis (lexing)
● Characters recognition
● Transform chars to tokens
● Lexer generator : Re2c
● http://re2c.org/
● http://www.php.net/manual/fr/tokens.php
● highlight_file()
● highlight_string()
● compile_file()
● compile_string()
10
Sementical analysis (parsing)
● "Understands" a set of tokens
● Defines the language syntax
● Parser generator : GNU/Bison (LALR)
● Foreach token or token set
● → Execute a function to generate an AST statement
● → Goto next token
● → Can generate "Parse error" and halt
● Very tied to lexical analyzer
11
zend_language_parser.y
● ext/tokenizer
statement:
'{' inner_statement_list '}' { $$ = $2; }
| if_stmt { $$ = $1; }
| alt_if_stmt { $$ = $1; }
| T_WHILE '(' expr ')' while_statement
{ $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); }
| T_DO statement T_WHILE '(' expr ')' ';'
{ $$ = zend_ast_create(ZEND_AST_DO_WHILE, $2, $5); }
| T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement
{ $$ = zend_ast_create(ZEND_AST_FOR, $3, $5, $7, $9); }
| T_SWITCH '(' expr ')' switch_case_list
{ $$ = zend_ast_create(ZEND_AST_SWITCH, $3, $5); }
| T_BREAK optional_expr ';' { $$ = zend_ast_create(ZEND_AST_BREAK, $2); }
| T_CONTINUE optional_expr ';' { $$ = zend_ast_create(ZEND_AST_CONTINUE, $2); }
| T_RETURN optional_expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); }
$(YACC) -p zend -v -d
$(srcdir)/zend_language_parser.y
-o zend_language_parser.c
12
Compilation
● Invoked on final AST
● Userland AST: https://github.com/nikic/php-ast
● Creates an OPCodes array
● OPCode = low level VM instruction
● Somehow similar to low level assembly
● Compilation step is very heavy
● Lots of checks and memory accesses
● address resolutions and computations
● many stacks and memory pools
● Some early optimizations/computations are performed
13
Optimization
● Optimizations are done by ext/opcache
● The optimizer is very heavy (in PHP 7)
● Steps are defined in opcache.optimization_level INI setting
#define ZEND_OPTIMIZER_PASS_1 (1<<0) /* CSE, STRING construction */
#define ZEND_OPTIMIZER_PASS_2 (1<<1) /* Constant conversion and jumps */
#define ZEND_OPTIMIZER_PASS_3 (1<<2) /* ++, +=, series of jumps */
#define ZEND_OPTIMIZER_PASS_4 (1<<3) /* INIT_FCALL_BY_NAME -> DO_FCALL */
#define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */
#define ZEND_OPTIMIZER_PASS_6 (1<<5) /* DFA based optimization */
#define ZEND_OPTIMIZER_PASS_7 (1<<6) /* CALL GRAPH optimization */
#define ZEND_OPTIMIZER_PASS_8 (1<<7) /* SCCP (constant propagation) */
#define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */
#define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */
#define ZEND_OPTIMIZER_PASS_11 (1<<10) /* Merge equal constants */
#define ZEND_OPTIMIZER_PASS_12 (1<<11) /* Adjust used stack */
#define ZEND_OPTIMIZER_PASS_13 (1<<12) /* Remove unused variables */
#define ZEND_OPTIMIZER_PASS_14 (1<<13) /* DCE (dead code elimination) */
#define ZEND_OPTIMIZER_PASS_15 (1<<14) /* (unsafe) Collect constants */
#define ZEND_OPTIMIZER_PASS_16 (1<<15) /* Inline functions */
14
First easy example
<?php
print 'foo';
15
Compilation easy example
<?php
print 'foo';
<ST_IN_SCRIPTING>"print" {
return T_PRINT;
}
T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); }
lexing
parsing
16
Compilation easy example
case ZEND_AST_PRINT:
zend_compile_print(result, ast);
return;
compiling
T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); }
void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */
{
zend_op *opline;
zend_ast *expr_ast = ast->child[0];
znode expr_node;
zend_compile_expr(&expr_node, expr_ast);
opline = zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL);
opline->extended_value = 1;
result->op_type = IS_CONST;
ZVAL_LONG(&result->u.constant, 1);
}
17
Execution
● Execute OPCodes
● Most complex part of Zend Engine
● VM executor
● zend_vm_execute.h
● Each OPCode
● is run through a handler() function
● "zend_vm_handler"
● runs the instructions in an infinite dipatch
loop
● Branching possibles (loops, catch blocks,
gotos, etc...)
Startup
Shutdown
zend_compile_file()
zend_execute()
18
ZEND_ECHO
ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY)
{
USE_OPLINE
zend_free_op free_op1;
zval *z;
SAVE_OPLINE();
z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
if (Z_TYPE_P(z) == IS_STRING) {
zend_string *str = Z_STR_P(z);
if (ZSTR_LEN(str) != 0) {
zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
}
} else {
zend_string *str = _zval_get_string_func(z);
if (ZSTR_LEN(str) != 0) {
zend_write(ZSTR_VAL(str), ZSTR_LEN(str));
} else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) {
GET_OP1_UNDEF_CV(z, BP_VAR_R);
}
zend_string_release(str);
}
19
OPCode ?
● php
-dzend_extension=opcache
-dopcache.enable_cli=1
-dopcache.opt_debug_level=0x30000
/tmp/script.php
L0 (3): CV0($options) = RECV 1
L1 (5): CV1($invalid) = QM_ASSIGN array(...)
L2 (6): V4 = FE_RESET_R CV0($options) L18
L3 (6): T5 = FE_FETCH_R V4 CV2($value) L18
L4 (6): ASSIGN CV3($key) T5
...
20
Many OPCodes
● OPCodes are low level VM instructions
● Many of them, more and more as PHP evolves
● ~ 200 flavors in PHP 7
● See the list from Zend/zend_vm_opcodes.h
● ZEND_ADD
● ZEND_DECLARE_ANON_CLASS
● ZEND_FE_RESET
● ZEND_ADD_TRAIT
● ZEND_YIELD_FROM
● ...
21
OPCode handlers
● Each OPCode is treated by a handler (a function)
● It takes up to 3 arguments and produces exactly one
result
● Arguments and result are "variable" like you know them
● ZEND_ADD(num1, num2) : result_num
● ZEND_DECLARE_ANON_CLASS(class) : result_bool
● ZEND_FE_RESET(array_or_object) : result
● ZEND_ADD_TRAIT(class, trait) : result_bool
● ZEND_YIELD_FROM(cur_gen, gen_from) : result
22
ZEND_CONCAT example
ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV)
{
USE_OPLINE
zend_free_op free_op1, free_op2;
zval *op1, *op2;
op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R);
op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R);
if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) &&
(OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) {
zend_string *op1_str = Z_STR_P(op1);
zend_string *op2_str = Z_STR_P(op2);
zend_string *str;
if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV &&
!ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) {
size_t len = ZSTR_LEN(op1_str);
str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0);
memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1);
ZVAL_NEW_STR(EX_VAR(opline->result.var), str);
FREE_OP2();
}
...
23
More complex example
function check_options(array $options)
{
$invalid = [];
foreach ($options as $key => $value) {
if (array_key_exists($key, $this->options)) {
$this->options[$key] = $value;
} else {
$invalid[] = $key;
}
}
}
L0 (4): CV0($options) = RECV 1
L1 (6): ASSIGN CV1($invalid) array(...)
L2 (7): V5 = FE_RESET_R CV0($options) L18
L3 (7): T6 = FE_FETCH_R V5 CV2($value) L18
L4 (7): ASSIGN CV3($key) T6
L5 (8): INIT_FCALL 2 112 string("array_key_exists")
L6 (8): SEND_VAR CV3($key) 1
L7 (8): T8 = FETCH_OBJ_R THIS string("options")
L8 (8): SEND_VAL T8 2
L9 (8): V9 = DO_ICALL
L10 (8): JMPZ V9 L15
L11 (9): V10 = FETCH_OBJ_W THIS string("options")
L12 (9): ASSIGN_DIM V10 CV3($key)
L13 (9): OP_DATA CV2($value)
L14 (9): JMP L17
L15 (11): ASSIGN_DIM CV1($invalid) NEXT
L16 (11): OP_DATA CV3($key)
L17 (7): JMP L3
L18 (7): FE_FREE V5
L19 (14): RETURN null
24
OPCode Cache
● First time
● Compile
● Cache to SHM or cache file
● Execute
● Then, if file did not change
● Load from SHM or cache file
● Execute
● Compilation is very heavy
● Optimization can be as well
25
Compilation / Execution
function foo()
{
$data = file('/etc/fstab');
sort($data);
return $data;
}
for($i=0; $i<=$argv[1]; $i++)
{
$a = foo();
$a[] = range(0, $i);
$result[] = $a;
}
var_dump($result);
main()==>run_init::tmp/php.php//1 241
main()==>compile::tmp/php.php//1 89
main()==>run_init::tmp/php.php//1 1731
main()==>compile::tmp/php.php//1 89
argv = 1
argv = 10
26
Other topics in quick
27
CLI
● Even if more and more used, PHP has not been designed
to run in CLI (for long running scripts)
● In long run CLI ("consumers"), the VM never stops
● PHP never stops, thus never reaches its "cleaning memory
step"
● The "current request" memory is then never freed
● Even with GC on, the programmer has to really take care
not to create "memory leaks"
● And for that he has to master how PHP works internally
● Or use a low level memory debugger, like valgrind/massif
● OPCode caches and optimizers are pretty useless to CLI
● Optimization can be worth it
● Compilation prevention is useless as runtime will take a lot
28
JIT ?
● JIT is a complex topic, and coming to PHP 8
● Still under development
● It should accelerate very CPU intensive tasks
● Aka : not web applications, usually
● Until you really treat that many data per request, which
you shouldn't do anyway with PHP.
● But CLI scripts will mainly benefit from JIT (composer ?)
● Take care as it wont accelerate any IO intensive tasks
● And we tend to run some using PHP nowadays
● (Aka "event loops" and things like that)
29
PHP's memory consumption
● Know what you are talking about and what you're doing
● Know your OS and memory allocators
● memory_get_usage(): size used by your runtime code
● memory_get_usage(true): size allocated through the OS
● ZendMM caches blocks
● use gc_mem_caches() to reclaim them if needed
● Use your OS to be accurate
php> echo memory_get_usage();
625272
php> echo memory_get_usage(1);
786432
cat /proc/13399/status
Name:php
State: S (sleeping)
VmPeak: 154440 kB
VmSize: 133700 kB
VmRSS: 10304 kB
VmData: 4316 kB
VmStk: 136 kB
VmExe: 9876 kB
30
A software VM
● PHP internally works the same as
● Java
● Python
● Ruby
● Lua
● [... others ]
● But PHP's VM is not threaded, it runs a monolithic path
● PHP's VM compiler/optimizer/interpreter are merged
into PHP source code
● zend_compile.c
● ext/opcache/Optimizer/zend_optimizer.c
● zend_vm_def.h / zend_execute.c
31
Thank you for listening

Weitere ähnliche Inhalte

Was ist angesagt?

The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life CycleXinchen Hui
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objectsjulien pauli
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPGuilherme Blanco
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)julien pauli
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7julien pauli
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?Ravi Raj
 
Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Moriyoshi Koizumi
 
Php7 extensions workshop
Php7 extensions workshopPhp7 extensions workshop
Php7 extensions workshopjulien pauli
 
OpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpen Gurukul
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for DummiesElizabeth Smith
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlHideaki Ohno
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Platonov Sergey
 
Mysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionMysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionjulien pauli
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memoryjulien pauli
 
Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshopjulien pauli
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itSergey Platonov
 

Was ist angesagt? (20)

The Php Life Cycle
The Php Life CycleThe Php Life Cycle
The Php Life Cycle
 
Understanding PHP objects
Understanding PHP objectsUnderstanding PHP objects
Understanding PHP objects
 
Building Custom PHP Extensions
Building Custom PHP ExtensionsBuilding Custom PHP Extensions
Building Custom PHP Extensions
 
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHPIPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
IPC2010SE Doctrine2 Enterprise Persistence Layer for PHP
 
Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)Php in 2013 (Web-5 2013 conference)
Php in 2013 (Web-5 2013 conference)
 
Profiling php5 to php7
Profiling php5 to php7Profiling php5 to php7
Profiling php5 to php7
 
How PHP Works ?
How PHP Works ?How PHP Works ?
How PHP Works ?
 
Phpをいじり倒す10の方法
Phpをいじり倒す10の方法Phpをいじり倒す10の方法
Phpをいじり倒す10の方法
 
Php7 extensions workshop
Php7 extensions workshopPhp7 extensions workshop
Php7 extensions workshop
 
OpenGurukul : Language : PHP
OpenGurukul : Language : PHPOpenGurukul : Language : PHP
OpenGurukul : Language : PHP
 
Отладка в GDB
Отладка в GDBОтладка в GDB
Отладка в GDB
 
Php Extensions for Dummies
Php Extensions for DummiesPhp Extensions for Dummies
Php Extensions for Dummies
 
Yapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed PerlYapcasia2011 - Hello Embed Perl
Yapcasia2011 - Hello Embed Perl
 
Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.Евгений Крутько, Многопоточные вычисления, современный подход.
Евгений Крутько, Многопоточные вычисления, современный подход.
 
Mysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extensionMysqlnd, an unknown powerful PHP extension
Mysqlnd, an unknown powerful PHP extension
 
Understanding PHP memory
Understanding PHP memoryUnderstanding PHP memory
Understanding PHP memory
 
PHP 7 new engine
PHP 7 new enginePHP 7 new engine
PHP 7 new engine
 
Php extensions workshop
Php extensions workshopPhp extensions workshop
Php extensions workshop
 
Npc14
Npc14Npc14
Npc14
 
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against itEvgeniy Muralev, Mark Vince, Working with the compiler, not against it
Evgeniy Muralev, Mark Vince, Working with the compiler, not against it
 

Ähnlich wie PHP Internals and Virtual Machine

Php opcodes sep2008
Php opcodes sep2008Php opcodes sep2008
Php opcodes sep2008bengiuliano
 
Perl - laziness, impatience, hubris, and one liners
Perl - laziness, impatience, hubris, and one linersPerl - laziness, impatience, hubris, and one liners
Perl - laziness, impatience, hubris, and one linersKirk Kimmel
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Lin Yo-An
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6Wim Godden
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Joseph Scott
 
"Развитие ветки PHP-7"
"Развитие ветки PHP-7""Развитие ветки PHP-7"
"Развитие ветки PHP-7"Badoo Development
 
Bare metal performance in Elixir
Bare metal performance in ElixirBare metal performance in Elixir
Bare metal performance in ElixirAaron Seigo
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside OutFerenc Kovács
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environmentEvaldo Felipe
 
PHP Performance SfLive 2010
PHP Performance SfLive 2010PHP Performance SfLive 2010
PHP Performance SfLive 2010De Cock Xavier
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5Wim Godden
 
Ob1k presentation at Java.IL
Ob1k presentation at Java.ILOb1k presentation at Java.IL
Ob1k presentation at Java.ILEran Harel
 
Linux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudLinux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudAndrea Righi
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5Wim Godden
 
DeVry GSP 115 All Assignments latest
DeVry GSP 115 All Assignments latestDeVry GSP 115 All Assignments latest
DeVry GSP 115 All Assignments latestAtifkhilji
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges✅ William Pinaud
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performancesjulien pauli
 

Ähnlich wie PHP Internals and Virtual Machine (20)

Php opcodes sep2008
Php opcodes sep2008Php opcodes sep2008
Php opcodes sep2008
 
Perl - laziness, impatience, hubris, and one liners
Perl - laziness, impatience, hubris, and one linersPerl - laziness, impatience, hubris, and one liners
Perl - laziness, impatience, hubris, and one liners
 
Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015Code Generation in PHP - PHPConf 2015
Code Generation in PHP - PHPConf 2015
 
The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6The why and how of moving to PHP 5.5/5.6
The why and how of moving to PHP 5.5/5.6
 
Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )Anatomy of a PHP Request ( UTOSC 2010 )
Anatomy of a PHP Request ( UTOSC 2010 )
 
"Развитие ветки PHP-7"
"Развитие ветки PHP-7""Развитие ветки PHP-7"
"Развитие ветки PHP-7"
 
Bare metal performance in Elixir
Bare metal performance in ElixirBare metal performance in Elixir
Bare metal performance in Elixir
 
Php 5.6 From the Inside Out
Php 5.6 From the Inside OutPhp 5.6 From the Inside Out
Php 5.6 From the Inside Out
 
Plpgsql internals
Plpgsql internalsPlpgsql internals
Plpgsql internals
 
DevOps in PHP environment
DevOps in PHP environmentDevOps in PHP environment
DevOps in PHP environment
 
PHP Performance SfLive 2010
PHP Performance SfLive 2010PHP Performance SfLive 2010
PHP Performance SfLive 2010
 
The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5The why and how of moving to PHP 5.4/5.5
The why and how of moving to PHP 5.4/5.5
 
Ob1k presentation at Java.IL
Ob1k presentation at Java.ILOb1k presentation at Java.IL
Ob1k presentation at Java.IL
 
Linux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloudLinux kernel tracing superpowers in the cloud
Linux kernel tracing superpowers in the cloud
 
The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5The why and how of moving to php 5.4/5.5
The why and how of moving to php 5.4/5.5
 
DeVry GSP 115 All Assignments latest
DeVry GSP 115 All Assignments latestDeVry GSP 115 All Assignments latest
DeVry GSP 115 All Assignments latest
 
Php 7 evolution
Php 7 evolutionPhp 7 evolution
Php 7 evolution
 
PHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP LimogesPHP in 2018 - Q4 - AFUP Limoges
PHP in 2018 - Q4 - AFUP Limoges
 
Symfony live 2017_php7_performances
Symfony live 2017_php7_performancesSymfony live 2017_php7_performances
Symfony live 2017_php7_performances
 
PHP7 Presentation
PHP7 PresentationPHP7 Presentation
PHP7 Presentation
 

Mehr von julien pauli

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019julien pauli
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGjulien pauli
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourselfjulien pauli
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesjulien pauli
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5julien pauli
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPjulien pauli
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensionsjulien pauli
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4julien pauli
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHPjulien pauli
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentationjulien pauli
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPjulien pauli
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHPjulien pauli
 

Mehr von julien pauli (14)

Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019Doctrine with Symfony - SymfonyCon 2019
Doctrine with Symfony - SymfonyCon 2019
 
Dns
DnsDns
Dns
 
Basics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNGBasics of Cryptography - Stream ciphers and PRNG
Basics of Cryptography - Stream ciphers and PRNG
 
Mastering your home network - Do It Yourself
Mastering your home network - Do It YourselfMastering your home network - Do It Yourself
Mastering your home network - Do It Yourself
 
SymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performancesSymfonyCon 2017 php7 performances
SymfonyCon 2017 php7 performances
 
Tcpip
TcpipTcpip
Tcpip
 
PHP 7 performances from PHP 5
PHP 7 performances from PHP 5PHP 7 performances from PHP 5
PHP 7 performances from PHP 5
 
Communications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHPCommunications Réseaux et HTTP avec PHP
Communications Réseaux et HTTP avec PHP
 
PHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_ExtensionsPHPTour-2011-PHP_Extensions
PHPTour-2011-PHP_Extensions
 
PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4PHPTour 2011 - PHP5.4
PHPTour 2011 - PHP5.4
 
Patterns and OOP in PHP
Patterns and OOP in PHPPatterns and OOP in PHP
Patterns and OOP in PHP
 
ZendFramework2 - Présentation
ZendFramework2 - PrésentationZendFramework2 - Présentation
ZendFramework2 - Présentation
 
AlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHPAlterWay SolutionsLinux Outils Industrialisation PHP
AlterWay SolutionsLinux Outils Industrialisation PHP
 
Apache for développeurs PHP
Apache for développeurs PHPApache for développeurs PHP
Apache for développeurs PHP
 

Kürzlich hochgeladen

『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书rnrncn29
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxDyna Gilbert
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)Christopher H Felton
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationLinaWolf1
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxeditsforyah
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Paul Calvano
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作ys8omjxb
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一Fs
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predieusebiomeyer
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleanscorenetworkseo
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa494f574xmv
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书zdzoqco
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书rnrncn29
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITMgdsc13
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012rehmti665
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Dana Luther
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Sonam Pathan
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Sonam Pathan
 

Kürzlich hochgeladen (20)

Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort ServiceHot Sexy call girls in  Rk Puram 🔝 9953056974 🔝 Delhi escort Service
Hot Sexy call girls in Rk Puram 🔝 9953056974 🔝 Delhi escort Service
 
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
『澳洲文凭』买詹姆士库克大学毕业证书成绩单办理澳洲JCU文凭学位证书
 
Top 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptxTop 10 Interactive Website Design Trends in 2024.pptx
Top 10 Interactive Website Design Trends in 2024.pptx
 
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
A Good Girl's Guide to Murder (A Good Girl's Guide to Murder, #1)
 
PHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 DocumentationPHP-based rendering of TYPO3 Documentation
PHP-based rendering of TYPO3 Documentation
 
Q4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptxQ4-1-Illustrating-Hypothesis-Testing.pptx
Q4-1-Illustrating-Hypothesis-Testing.pptx
 
Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24Font Performance - NYC WebPerf Meetup April '24
Font Performance - NYC WebPerf Meetup April '24
 
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Serviceyoung call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
young call girls in Uttam Nagar🔝 9953056974 🔝 Delhi escort Service
 
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
Potsdam FH学位证,波茨坦应用技术大学毕业证书1:1制作
 
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
定制(AUT毕业证书)新西兰奥克兰理工大学毕业证成绩单原版一比一
 
SCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is prediSCM Symposium PPT Format Customer loyalty is predi
SCM Symposium PPT Format Customer loyalty is predi
 
Elevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New OrleansElevate Your Business with Our IT Expertise in New Orleans
Elevate Your Business with Our IT Expertise in New Orleans
 
Film cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasaFilm cover research (1).pptxsdasdasdasdasdasa
Film cover research (1).pptxsdasdasdasdasdasa
 
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
办理多伦多大学毕业证成绩单|购买加拿大UTSG文凭证书
 
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
『澳洲文凭』买拉筹伯大学毕业证书成绩单办理澳洲LTU文凭学位证书
 
Git and Github workshop GDSC MLRITM
Git and Github  workshop GDSC MLRITMGit and Github  workshop GDSC MLRITM
Git and Github workshop GDSC MLRITM
 
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
Call Girls South Delhi Delhi reach out to us at ☎ 9711199012
 
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
Packaging the Monolith - PHP Tek 2024 (Breaking it down one bite at a time)
 
Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170Call Girls Near The Suryaa Hotel New Delhi 9873777170
Call Girls Near The Suryaa Hotel New Delhi 9873777170
 
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
Call Girls In The Ocean Pearl Retreat Hotel New Delhi 9873777170
 

PHP Internals and Virtual Machine

  • 2. 2 Hello ● Julien PAULI ● Programming in PHP since early 2000s ● PHP Internals hacker and trainer ● PHP 5.5/5.6 Release Manager ● Working at SensioLabs in Paris - Blackfire ● Writing PHP tech articles and books ● http://phpinternalsbook.com ● @julienpauli - github.com/jpauli - jpauli@php.net ● Like working on OSS such as PHP :-)
  • 3. 3 PHP ● A program in itself ● Written in C ● Goal : Define a programming Web language ● High level, interpreted ● Interpreted language ● Less efficient than native-instr compiled language ● but simpler to handle
  • 5. 5 PHP from inside ● A software virtual machine ● Compiler/Executor ● intermediate OPCode ● Mono Thread, Mono process ● Automatic dynamic memory management ● Memory Manager ● Garbage collector
  • 6. 6 Zend Engine ● The heart of PHP ● An extensible part ● extensions and zend_extensions can change it ● A Virtual Machine ● A compiler ● An executor ● Some utilities ● OPCache ● A Zend extension that plays with the engine deeply ● Compiler optimizer is stored into OPCache
  • 7. 7 Request treatment steps ● Startup (memory allocations) ● Compilation ● Lexical and syntaxic analysis ● Compilation (OP Code generation) ● Execution ● OPCode interpretation ● Several VM flavors ● Include/require/eval = go back to compilation ● Shutdown (free resources) ● "Share nothing architecture" Startup Shutdown zend_compile_file() zend_execute()
  • 8. 8 Script execution ● Compilation ● Optmization (OPCache) ● Execution ● Destruction
  • 9. 9 Lexical analysis (lexing) ● Characters recognition ● Transform chars to tokens ● Lexer generator : Re2c ● http://re2c.org/ ● http://www.php.net/manual/fr/tokens.php ● highlight_file() ● highlight_string() ● compile_file() ● compile_string()
  • 10. 10 Sementical analysis (parsing) ● "Understands" a set of tokens ● Defines the language syntax ● Parser generator : GNU/Bison (LALR) ● Foreach token or token set ● → Execute a function to generate an AST statement ● → Goto next token ● → Can generate "Parse error" and halt ● Very tied to lexical analyzer
  • 11. 11 zend_language_parser.y ● ext/tokenizer statement: '{' inner_statement_list '}' { $$ = $2; } | if_stmt { $$ = $1; } | alt_if_stmt { $$ = $1; } | T_WHILE '(' expr ')' while_statement { $$ = zend_ast_create(ZEND_AST_WHILE, $3, $5); } | T_DO statement T_WHILE '(' expr ')' ';' { $$ = zend_ast_create(ZEND_AST_DO_WHILE, $2, $5); } | T_FOR '(' for_exprs ';' for_exprs ';' for_exprs ')' for_statement { $$ = zend_ast_create(ZEND_AST_FOR, $3, $5, $7, $9); } | T_SWITCH '(' expr ')' switch_case_list { $$ = zend_ast_create(ZEND_AST_SWITCH, $3, $5); } | T_BREAK optional_expr ';' { $$ = zend_ast_create(ZEND_AST_BREAK, $2); } | T_CONTINUE optional_expr ';' { $$ = zend_ast_create(ZEND_AST_CONTINUE, $2); } | T_RETURN optional_expr ';' { $$ = zend_ast_create(ZEND_AST_RETURN, $2); } $(YACC) -p zend -v -d $(srcdir)/zend_language_parser.y -o zend_language_parser.c
  • 12. 12 Compilation ● Invoked on final AST ● Userland AST: https://github.com/nikic/php-ast ● Creates an OPCodes array ● OPCode = low level VM instruction ● Somehow similar to low level assembly ● Compilation step is very heavy ● Lots of checks and memory accesses ● address resolutions and computations ● many stacks and memory pools ● Some early optimizations/computations are performed
  • 13. 13 Optimization ● Optimizations are done by ext/opcache ● The optimizer is very heavy (in PHP 7) ● Steps are defined in opcache.optimization_level INI setting #define ZEND_OPTIMIZER_PASS_1 (1<<0) /* CSE, STRING construction */ #define ZEND_OPTIMIZER_PASS_2 (1<<1) /* Constant conversion and jumps */ #define ZEND_OPTIMIZER_PASS_3 (1<<2) /* ++, +=, series of jumps */ #define ZEND_OPTIMIZER_PASS_4 (1<<3) /* INIT_FCALL_BY_NAME -> DO_FCALL */ #define ZEND_OPTIMIZER_PASS_5 (1<<4) /* CFG based optimization */ #define ZEND_OPTIMIZER_PASS_6 (1<<5) /* DFA based optimization */ #define ZEND_OPTIMIZER_PASS_7 (1<<6) /* CALL GRAPH optimization */ #define ZEND_OPTIMIZER_PASS_8 (1<<7) /* SCCP (constant propagation) */ #define ZEND_OPTIMIZER_PASS_9 (1<<8) /* TMP VAR usage */ #define ZEND_OPTIMIZER_PASS_10 (1<<9) /* NOP removal */ #define ZEND_OPTIMIZER_PASS_11 (1<<10) /* Merge equal constants */ #define ZEND_OPTIMIZER_PASS_12 (1<<11) /* Adjust used stack */ #define ZEND_OPTIMIZER_PASS_13 (1<<12) /* Remove unused variables */ #define ZEND_OPTIMIZER_PASS_14 (1<<13) /* DCE (dead code elimination) */ #define ZEND_OPTIMIZER_PASS_15 (1<<14) /* (unsafe) Collect constants */ #define ZEND_OPTIMIZER_PASS_16 (1<<15) /* Inline functions */
  • 15. 15 Compilation easy example <?php print 'foo'; <ST_IN_SCRIPTING>"print" { return T_PRINT; } T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); } lexing parsing
  • 16. 16 Compilation easy example case ZEND_AST_PRINT: zend_compile_print(result, ast); return; compiling T_PRINT expr { $$ = zend_ast_create(ZEND_AST_PRINT, $2); } void zend_compile_print(znode *result, zend_ast *ast) /* {{{ */ { zend_op *opline; zend_ast *expr_ast = ast->child[0]; znode expr_node; zend_compile_expr(&expr_node, expr_ast); opline = zend_emit_op(NULL, ZEND_ECHO, &expr_node, NULL); opline->extended_value = 1; result->op_type = IS_CONST; ZVAL_LONG(&result->u.constant, 1); }
  • 17. 17 Execution ● Execute OPCodes ● Most complex part of Zend Engine ● VM executor ● zend_vm_execute.h ● Each OPCode ● is run through a handler() function ● "zend_vm_handler" ● runs the instructions in an infinite dipatch loop ● Branching possibles (loops, catch blocks, gotos, etc...) Startup Shutdown zend_compile_file() zend_execute()
  • 18. 18 ZEND_ECHO ZEND_VM_HANDLER(40, ZEND_ECHO, CONST|TMPVAR|CV, ANY) { USE_OPLINE zend_free_op free_op1; zval *z; SAVE_OPLINE(); z = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); if (Z_TYPE_P(z) == IS_STRING) { zend_string *str = Z_STR_P(z); if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } } else { zend_string *str = _zval_get_string_func(z); if (ZSTR_LEN(str) != 0) { zend_write(ZSTR_VAL(str), ZSTR_LEN(str)); } else if (OP1_TYPE == IS_CV && UNEXPECTED(Z_TYPE_P(z) == IS_UNDEF)) { GET_OP1_UNDEF_CV(z, BP_VAR_R); } zend_string_release(str); }
  • 19. 19 OPCode ? ● php -dzend_extension=opcache -dopcache.enable_cli=1 -dopcache.opt_debug_level=0x30000 /tmp/script.php L0 (3): CV0($options) = RECV 1 L1 (5): CV1($invalid) = QM_ASSIGN array(...) L2 (6): V4 = FE_RESET_R CV0($options) L18 L3 (6): T5 = FE_FETCH_R V4 CV2($value) L18 L4 (6): ASSIGN CV3($key) T5 ...
  • 20. 20 Many OPCodes ● OPCodes are low level VM instructions ● Many of them, more and more as PHP evolves ● ~ 200 flavors in PHP 7 ● See the list from Zend/zend_vm_opcodes.h ● ZEND_ADD ● ZEND_DECLARE_ANON_CLASS ● ZEND_FE_RESET ● ZEND_ADD_TRAIT ● ZEND_YIELD_FROM ● ...
  • 21. 21 OPCode handlers ● Each OPCode is treated by a handler (a function) ● It takes up to 3 arguments and produces exactly one result ● Arguments and result are "variable" like you know them ● ZEND_ADD(num1, num2) : result_num ● ZEND_DECLARE_ANON_CLASS(class) : result_bool ● ZEND_FE_RESET(array_or_object) : result ● ZEND_ADD_TRAIT(class, trait) : result_bool ● ZEND_YIELD_FROM(cur_gen, gen_from) : result
  • 22. 22 ZEND_CONCAT example ZEND_VM_HANDLER(8, ZEND_CONCAT, CONST|TMPVAR|CV, CONST|TMPVAR|CV) { USE_OPLINE zend_free_op free_op1, free_op2; zval *op1, *op2; op1 = GET_OP1_ZVAL_PTR_UNDEF(BP_VAR_R); op2 = GET_OP2_ZVAL_PTR_UNDEF(BP_VAR_R); if ((OP1_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op1) == IS_STRING)) && (OP2_TYPE == IS_CONST || EXPECTED(Z_TYPE_P(op2) == IS_STRING))) { zend_string *op1_str = Z_STR_P(op1); zend_string *op2_str = Z_STR_P(op2); zend_string *str; if (OP1_TYPE != IS_CONST && OP1_TYPE != IS_CV && !ZSTR_IS_INTERNED(op1_str) && GC_REFCOUNT(op1_str) == 1) { size_t len = ZSTR_LEN(op1_str); str = zend_string_extend(op1_str, len + ZSTR_LEN(op2_str), 0); memcpy(ZSTR_VAL(str) + len, ZSTR_VAL(op2_str), ZSTR_LEN(op2_str)+1); ZVAL_NEW_STR(EX_VAR(opline->result.var), str); FREE_OP2(); } ...
  • 23. 23 More complex example function check_options(array $options) { $invalid = []; foreach ($options as $key => $value) { if (array_key_exists($key, $this->options)) { $this->options[$key] = $value; } else { $invalid[] = $key; } } } L0 (4): CV0($options) = RECV 1 L1 (6): ASSIGN CV1($invalid) array(...) L2 (7): V5 = FE_RESET_R CV0($options) L18 L3 (7): T6 = FE_FETCH_R V5 CV2($value) L18 L4 (7): ASSIGN CV3($key) T6 L5 (8): INIT_FCALL 2 112 string("array_key_exists") L6 (8): SEND_VAR CV3($key) 1 L7 (8): T8 = FETCH_OBJ_R THIS string("options") L8 (8): SEND_VAL T8 2 L9 (8): V9 = DO_ICALL L10 (8): JMPZ V9 L15 L11 (9): V10 = FETCH_OBJ_W THIS string("options") L12 (9): ASSIGN_DIM V10 CV3($key) L13 (9): OP_DATA CV2($value) L14 (9): JMP L17 L15 (11): ASSIGN_DIM CV1($invalid) NEXT L16 (11): OP_DATA CV3($key) L17 (7): JMP L3 L18 (7): FE_FREE V5 L19 (14): RETURN null
  • 24. 24 OPCode Cache ● First time ● Compile ● Cache to SHM or cache file ● Execute ● Then, if file did not change ● Load from SHM or cache file ● Execute ● Compilation is very heavy ● Optimization can be as well
  • 25. 25 Compilation / Execution function foo() { $data = file('/etc/fstab'); sort($data); return $data; } for($i=0; $i<=$argv[1]; $i++) { $a = foo(); $a[] = range(0, $i); $result[] = $a; } var_dump($result); main()==>run_init::tmp/php.php//1 241 main()==>compile::tmp/php.php//1 89 main()==>run_init::tmp/php.php//1 1731 main()==>compile::tmp/php.php//1 89 argv = 1 argv = 10
  • 27. 27 CLI ● Even if more and more used, PHP has not been designed to run in CLI (for long running scripts) ● In long run CLI ("consumers"), the VM never stops ● PHP never stops, thus never reaches its "cleaning memory step" ● The "current request" memory is then never freed ● Even with GC on, the programmer has to really take care not to create "memory leaks" ● And for that he has to master how PHP works internally ● Or use a low level memory debugger, like valgrind/massif ● OPCode caches and optimizers are pretty useless to CLI ● Optimization can be worth it ● Compilation prevention is useless as runtime will take a lot
  • 28. 28 JIT ? ● JIT is a complex topic, and coming to PHP 8 ● Still under development ● It should accelerate very CPU intensive tasks ● Aka : not web applications, usually ● Until you really treat that many data per request, which you shouldn't do anyway with PHP. ● But CLI scripts will mainly benefit from JIT (composer ?) ● Take care as it wont accelerate any IO intensive tasks ● And we tend to run some using PHP nowadays ● (Aka "event loops" and things like that)
  • 29. 29 PHP's memory consumption ● Know what you are talking about and what you're doing ● Know your OS and memory allocators ● memory_get_usage(): size used by your runtime code ● memory_get_usage(true): size allocated through the OS ● ZendMM caches blocks ● use gc_mem_caches() to reclaim them if needed ● Use your OS to be accurate php> echo memory_get_usage(); 625272 php> echo memory_get_usage(1); 786432 cat /proc/13399/status Name:php State: S (sleeping) VmPeak: 154440 kB VmSize: 133700 kB VmRSS: 10304 kB VmData: 4316 kB VmStk: 136 kB VmExe: 9876 kB
  • 30. 30 A software VM ● PHP internally works the same as ● Java ● Python ● Ruby ● Lua ● [... others ] ● But PHP's VM is not threaded, it runs a monolithic path ● PHP's VM compiler/optimizer/interpreter are merged into PHP source code ● zend_compile.c ● ext/opcache/Optimizer/zend_optimizer.c ● zend_vm_def.h / zend_execute.c
  • 31. 31 Thank you for listening