Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.
PHP 7
What changed internally?
Nikita Popov
http://hhvm.com/blog/9293/lockdown-results-and-hhvm-performance
Memory optimization
Memory optimization
• Reduce number of allocations
Memory optimization
• Reduce number of allocations
Memory
Memory optimization
• Reduce number of allocations
Memory
Memory optimization
• Reduce number of allocations
• PHP 5 spends 20% of CPU time in the allocator
Memory
Memory optimization
• Reduce number of allocations
• Reduce memory usage
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L1D
1ns 32KB
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU
4ns
L2
256 K...
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L312ns
a few...
RAM
100ns
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
CPU L3...
RAM
100ns
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Memory access has high latency
• Less...
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Reduce indirection
Memory optimization
• Reduce number of allocations
• Reduce memory usage
• Reduce indirection
• Pointer points to pointer ...
Zvals: PHP 5
• Zval = Type + Value
value
ty
zval
Zvals: PHP 5
• Zval = Type + Value
value (simple):
null, bool, int, float
ty
zval
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval
Complex data structure:
string, array, object
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval
Complex data structure:
string, array, object
$a = [];Code:
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
Complex data structure:
string, array, object
$a = [...
Zvals: PHP 5
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
Complex data structure:
string, array, object
$a = [...
Zvals: PHP 5
• Zval = Type + Value + Refcount
value (complex)
refcount = 1 ty
zval *
zval
$a:
Complex data structure:
stri...
Zvals: PHP 5
• Zval = Type + Value + Refcount
value (complex)
refcount = 2 ty
zval *
zval
$a:
Complex data structure:
stri...
Zvals: PHP 7
• Zval = Type + Value
value (complex)
ty
zval *
zval
$a:
$a = [];
$b = $a;
Code:
zval *$b:
Complex data struc...
Zvals: PHP 7
• Zval = Type + Value
zval *
zval
$a:
$a = [];
$b = $a;
Code:
zval *$b:
Complex data structure:
string, array...
value (complex)
type_info
value (complex)
type_info
Zvals: PHP 7
• Zval = Type + Value
$a:
Complex data structure:
string,...
PHP 5 PHP 7
value (simple):
null, bool, int, float
refcount ty
gc_buffer
zval * value (simple): …
type_info
1 allocations
...
PHP 5 PHP 7
value (complex)
refcount ty
gc_root
zval *
Complex data structure:
string, array, object
value (complex)
type_...
val (char *)
len (int)
A B C 0
zval value:
PHP 5
zend_string *
refcount gc_info
hash
len (size_t)
A B C 0
val (char *)
len (int)
A B C 0
zval value: zval value:
PHP 5 PHP 7
[0]: (empty)
[1]: (empty)
[2]: (empty)
[3]: (empty)
hash()
“xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]: (empty)
hash()
“xyz”
data
key “xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
data
key “foo”
hash()
“xyz”
data
key “xyz”
Arrays: PHP 5
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
data
key “foo”
hash()
“xyz”
data
key “xyz”
Arrays: PHP 5
“bar”
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
data
key “foo”
next
data
key “bar”
next = NULL
hash()
“bar”
“xyz”
data
key “xyz”...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 5
head
tail
data
key “foo”
next
data
key “bar”
ne...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 7
data
key “foo”
next
data
key “bar”
next = NULL
...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 7
data
key “foo”
next
data
key “bar”
next = NULL
...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
“foo”
hash()
“bar”
“xyz”
Arrays: PHP 7
Bucket *
uint32_t
data
key “foo”
next
data
key ...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
hash()
“bar”
“xyz”
Arrays: PHP 7
Bucket *
uint32_t
data
key “foo”
next
data
key “bar”
...
[0]: (empty)
[1]:
[2]: (empty)
[3]:
hash()
“bar”
“xyz”
Arrays: PHP 7
Bucket *
uint32_t
TOMBSTONE
data
key “bar”
next = NUL...
PHP 5 PHP 7
Allocations: 2 + 2 per element 2 + 0 per element
Size: 72 + 112 per element 56 + 36 per element
Indirections (...
PHP 5 PHP 7
Allocations: 2 + 2 per element 2 + 0 per element
Size: 72 + 112 per element 56 + 36 per element
Indirections (...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5
Memory usa...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5 PHP 7
Memo...
Immutable arrays
$arrays = [];
for ($i = 0; $i < 1000000; ++$i) {
$arrays[] = [1, 2, 3, 4, 5, 6, 7, 8];
}
PHP 5 PHP 7 PHP ...
Objects
Objects
zval
object store bucket
actual object
properties table
PHP 5
property value
Objects
zval
object store bucket
actual object
properties table
zval
actual object
properties table
(including values)
+
P...
PHP 5 PHP 7
Allocations: 2 + 1 per property 1 + 0 per property
Size: 96 + 40 per property 48 + 16 per property
Indirection...
Integers
Integers
64-bit integers
on
64-bit Windows
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
AST
<?php
$a = 42;
$b = 24;
echo $a + $b;
<?php T_OPEN_TAG
$a T_VARIABLE
=
42 T_LNUMBER
;
$b T_VARIABLE
=
24 T_LNUMBER
;
e...
Virtual machine
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 5)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
SEND_VAL 1
SEND_VAL 2
DO_FC...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
VM stack
INI...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – stack management (PHP 7)
function foo($a, $b) {
return $a + $b;
}
foo(1, 2);
{main}
foo()
…
execute_data...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – inlined internal functions
• Functions with custom opcodes:
• strlen()
• is_*()
• defined()
• call_user_...
Virtual machine – global registers
zend_execute_data* execute_data;
const zend_op* opline;
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
Virtual machine – global registers
register zend_execute_data* execute_data __asm__("%r14");
register const zend_op* oplin...
@nikita_ppv
nikic@php.net
https://joind.in/15255
Upcoming SlideShare
Loading in …5
×

PHP 7 – What changed internally? (Forum PHP 2015)

4,675 views

Published on

One of the main selling points of PHP 7 is greatly improved performance, with many real-world applications now running twice as fast… But where do these improvements come from?

At the core of PHP 7 lies an engine rewrite with focus on improving memory usage and performance. This talk provides an overview of the most significant changes, briefly covering everything from data structure changes, over enhancements in the executor, to the new compiler implementation.

Published in: Technology
  • Be the first to comment

PHP 7 – What changed internally? (Forum PHP 2015)

  1. 1. PHP 7 What changed internally? Nikita Popov
  2. 2. http://hhvm.com/blog/9293/lockdown-results-and-hhvm-performance
  3. 3. Memory optimization
  4. 4. Memory optimization • Reduce number of allocations
  5. 5. Memory optimization • Reduce number of allocations Memory
  6. 6. Memory optimization • Reduce number of allocations Memory
  7. 7. Memory optimization • Reduce number of allocations • PHP 5 spends 20% of CPU time in the allocator Memory
  8. 8. Memory optimization • Reduce number of allocations • Reduce memory usage
  9. 9. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency
  10. 10. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU
  11. 11. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L1D 1ns 32KB
  12. 12. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU 4ns L2 256 KB L1D 1ns 32KB
  13. 13. Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  14. 14. RAM 100ns Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  15. 15. RAM 100ns Memory optimization • Reduce number of allocations • Reduce memory usage • Memory access has high latency • Less data => more fits into the cache CPU L312ns a few MB 4ns L2 256 KB L1D 1ns 32KB
  16. 16. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection
  17. 17. Memory optimization • Reduce number of allocations • Reduce memory usage • Reduce indirection • Pointer points to pointer pointing to pointer pointing to pointer pointing to pointer pointing to pointer pointing to what you actually want What you have What you want
  18. 18. Zvals: PHP 5 • Zval = Type + Value value ty zval
  19. 19. Zvals: PHP 5 • Zval = Type + Value value (simple): null, bool, int, float ty zval
  20. 20. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval Complex data structure: string, array, object
  21. 21. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval Complex data structure: string, array, object $a = [];Code:
  22. 22. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = [];Code:
  23. 23. Zvals: PHP 5 • Zval = Type + Value value (complex) ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code:
  24. 24. Zvals: PHP 5 • Zval = Type + Value + Refcount value (complex) refcount = 1 ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code:
  25. 25. Zvals: PHP 5 • Zval = Type + Value + Refcount value (complex) refcount = 2 ty zval * zval $a: Complex data structure: string, array, object $a = []; $b = $a; Code: zval *$b:
  26. 26. Zvals: PHP 7 • Zval = Type + Value value (complex) ty zval * zval $a: $a = []; $b = $a; Code: zval *$b: Complex data structure: string, array, object refcount = 2
  27. 27. Zvals: PHP 7 • Zval = Type + Value zval * zval $a: $a = []; $b = $a; Code: zval *$b: Complex data structure: string, array, object refcount = 2 value (complex) type_info
  28. 28. value (complex) type_info value (complex) type_info Zvals: PHP 7 • Zval = Type + Value $a: Complex data structure: string, array, object $b: refcount = 2 zval zval
  29. 29. PHP 5 PHP 7 value (simple): null, bool, int, float refcount ty gc_buffer zval * value (simple): … type_info 1 allocations 1 level of indirection 40 bytes no allocations no indirection 16 bytes
  30. 30. PHP 5 PHP 7 value (complex) refcount ty gc_root zval * Complex data structure: string, array, object value (complex) type_info Complex data structure: string, array, object refcount gc_info 2 allocations 2 levels of indirection 40 bytes 1 allocation 1 level of indirection 24 bytes
  31. 31. val (char *) len (int) A B C 0 zval value: PHP 5
  32. 32. zend_string * refcount gc_info hash len (size_t) A B C 0 val (char *) len (int) A B C 0 zval value: zval value: PHP 5 PHP 7
  33. 33. [0]: (empty) [1]: (empty) [2]: (empty) [3]: (empty) hash() “xyz” Arrays: PHP 5
  34. 34. [0]: (empty) [1]: [2]: (empty) [3]: (empty) hash() “xyz” data key “xyz” Arrays: PHP 5
  35. 35. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” hash() “xyz” data key “xyz” Arrays: PHP 5
  36. 36. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” hash() “xyz” data key “xyz” Arrays: PHP 5 “bar”
  37. 37. [0]: (empty) [1]: [2]: (empty) [3]: “foo” data key “foo” next data key “bar” next = NULL hash() “bar” “xyz” data key “xyz” next = NULL Arrays: PHP 5
  38. 38. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 5 head tail data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  39. 39. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 7 data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL head tail
  40. 40. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 7 data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  41. 41. [0]: (empty) [1]: [2]: (empty) [3]: “foo” hash() “bar” “xyz” Arrays: PHP 7 Bucket * uint32_t data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  42. 42. [0]: (empty) [1]: [2]: (empty) [3]: hash() “bar” “xyz” Arrays: PHP 7 Bucket * uint32_t data key “foo” next data key “bar” next = NULL data key “xyz” next = NULL
  43. 43. [0]: (empty) [1]: [2]: (empty) [3]: hash() “bar” “xyz” Arrays: PHP 7 Bucket * uint32_t TOMBSTONE data key “bar” next = NULL data key “xyz” next = NULL
  44. 44. PHP 5 PHP 7 Allocations: 2 + 2 per element 2 + 0 per element Size: 72 + 112 per element 56 + 36 per element Indirections (lookup): 4 2 Arrays: PHP 5 vs. PHP 7 (For arrays with unique values)
  45. 45. PHP 5 PHP 7 Allocations: 2 + 2 per element 2 + 0 per element Size: 72 + 112 per element 56 + 36 per element Indirections (lookup): 4 2 Arrays: PHP 5 vs. PHP 7 (For arrays with unique values)
  46. 46. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; }
  47. 47. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 Memory usage 1336 MB Execution time (create) 0.77 s Execution time (destroy) 1.45 s
  48. 48. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 PHP 7 Memory usage 1336 MB 391 MB Execution time (create) 0.77 s 0.29 s Execution time (destroy) 1.45 s 0.05 s
  49. 49. Immutable arrays $arrays = []; for ($i = 0; $i < 1000000; ++$i) { $arrays[] = [1, 2, 3, 4, 5, 6, 7, 8]; } PHP 5 PHP 7 PHP 7 with opcache Memory usage 1336 MB 391 MB 32 MB Execution time (create) 0.77 s 0.29 s 0.03 s Execution time (destroy) 1.45 s 0.05 s 0.002 s
  50. 50. Objects
  51. 51. Objects zval object store bucket actual object properties table PHP 5 property value
  52. 52. Objects zval object store bucket actual object properties table zval actual object properties table (including values) + PHP 5 PHP 7 property value
  53. 53. PHP 5 PHP 7 Allocations: 2 + 1 per property 1 + 0 per property Size: 96 + 40 per property 48 + 16 per property Indirections (prop val): 4 1 Objects: PHP 5 vs. PHP 7 (For objects with unique properties)
  54. 54. Integers
  55. 55. Integers 64-bit integers on 64-bit Windows
  56. 56. AST <?php $a = 42; $b = 24; echo $a + $b;
  57. 57. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; lex
  58. 58. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~2 ECHO ~2 RETURN 1 lex parse + compile
  59. 59. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~2 ECHO ~2 RETURN 1 lex parse compile stmts assign var 42 $a assign $b echo + $a $b var 24
  60. 60. AST <?php $a = 42; $b = 24; echo $a + $b; <?php T_OPEN_TAG $a T_VARIABLE = 42 T_LNUMBER ; $b T_VARIABLE = 24 T_LNUMBER ; echo T_ECHO $a T_VARIABLE + $b T_VARIABLE ; ASSIGN $a 42 ASSIGN $b 24 ADD $a $b ~0 ECHO ~0 RETURN 1 lex parse compile token_get_all() nikic/php-ast phpdbg -p stmts assign var 42 $a assign $b echo + $a $b var 24
  61. 61. Virtual machine
  62. 62. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2);
  63. 63. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo()
  64. 64. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … VM stack
  65. 65. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) VM stack arg[0] arg[1]
  66. 66. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) execute_data VM stack arg[0] arg[1] ~0 $a $b
  67. 67. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) execute_data int(1) int(2) VM stack arg[0] arg[1] ~0 $a $b
  68. 68. Virtual machine – stack management (PHP 5) function foo($a, $b) { return $a + $b; } foo(1, 2); SEND_VAL 1 SEND_VAL 2 DO_FCALL foo RECV $a RECV $b ADD $a $b ~0 RETURN ~0 {main} foo() … int(1) int(2) int(3) execute_data int(1) int(2) VM stack arg[0] arg[1] ~0 $a $b
  69. 69. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … VM stack INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  70. 70. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  71. 71. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  72. 72. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  73. 73. Virtual machine – stack management (PHP 7) function foo($a, $b) { return $a + $b; } foo(1, 2); {main} foo() … execute_data int(1) int(2) int(3) VM stack ~0 $a $b INIT_FCALL foo SEND_VAL 1 SEND_VAL 2 DO_FCALL RECV $a RECV $b ADD $a $b ~0 RETURN ~0
  74. 74. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array()
  75. 75. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str);
  76. 76. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str); Is this strlen() or foostrlen()?
  77. 77. Virtual machine – inlined internal functions • Functions with custom opcodes: • strlen() • is_*() • defined() • call_user_func() • call_user_func_array() • Only in global scope or for fully qualified calls namespace foo; echo strlen($str); This is definitely strlen()!
  78. 78. Virtual machine – global registers zend_execute_data* execute_data; const zend_op* opline;
  79. 79. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15");
  80. 80. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code
  81. 81. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code • Avoid reloading from executor_globals / execute_data
  82. 82. Virtual machine – global registers register zend_execute_data* execute_data __asm__("%r14"); register const zend_op* opline __asm__("%r15"); • Registers reserved in VM code • Avoid reloading from executor_globals / execute_data • Avoid save/restore during calls
  83. 83. @nikita_ppv nikic@php.net https://joind.in/15255

×