PHP 7 – What changed internally?
-
Upload
nikita-popov -
Category
Technology
-
view
5.100 -
download
1
Transcript of PHP 7 – What changed internally?
•Return type declarations
•Scalar type declarations
function startsWith(string $s1, string $s2) : bool {…}
211
254 256 273
627666
0
100
200
300
400
500
600
700
PHP 5.3 PHP 5.4 PHP 5.5 PHP 5.6 PHP 7 HHVM 3.7
Req
/ S
ec
Wordpress 4.1.1 (home, 20 c)
Stolen from Rasmus
value = ARRAY
refcount = 1
$a = [];$a[0] = $a;unset($a);
5
[0]:
[1]: (empty)
[2]: (empty)
…
[0]: (empty)
[1]: (empty)
[2]: (empty)
…
GC root buffer
value = ARRAY
refcount = 1
$a = [];$a[0] = $a;unset($a);
5
[0]:
[1]: (empty)
[2]: (empty)
…
[0]:
[1]: (empty)
[2]: (empty)
…
GC root buffer
value = ARRAY
refcount = 1
gc_root
$a = [];$a[0] = $a;unset($a);
5
[0]:
[1]: (empty)
[2]: (empty)
…
[0]:
[1]: (empty)
[2]: (empty)
…
GC root buffer
NULLFALSETRUELONGDOUBLESTRINGARRAYOBJECTRESOURCEREFERENCE 7
zend_string *
refcount type_info
hash
len (size_t)
A B C \0
NULLFALSETRUELONGDOUBLESTRINGARRAYOBJECTRESOURCEREFERENCE 7
zend_string *
refcount type_info
hash
len (size_t)
A B C \0
refcounted header
$s = “foobar”;
7
$s value
STRING
refcount = 1 type_info
hash = 0x80000652FDE460BE
len = 6
f o o b a r \0
$s = “foobar”;$t = $s;
7
$s value
STRING
$t value
STRING refcount = 2 type_info
hash = 0x80000652FDE460BE
len = 6
f o o b a r \0
$s = “foobar”;$t = $s;$u = $s;
7
$s value
STRING
$t value
STRING
$u value
STRING
refcount = 3 type_info
hash = 0x80000652FDE460BE
len = 6
f o o b a r \0
7
type type_flags const_flags
refcounted collectable copyable
simple types
string
interned string
array
object
resource
reference
7
type type_flags const_flags
refcounted collectable copyable
simple types
string
interned string
array
object
resource
reference
7
type type_flags const_flags
refcounted collectable copyable
simple types
string
interned string
array
object
resource
reference
7
type type_flags const_flags
refcounted collectable copyable
simple types
string
interned string
array
object
resource
reference
5
[0]: (empty)
[1]:
[2]: (empty)
[3]: (empty)
“foo”data
key “foo”
next“bar”
data
key “bar”
next = NULL
5
[0]: (empty)
[1]:
[2]: (empty)
[3]: (empty)
“foo”data
key “foo”
next
prev = NULL
“bar”
data
key “bar”
next = NULL
prev
5
data
listNext
listPrev
prev
next
key “foo”
zval
$a1 = [“foo” => 1,“bar” => 2];
$a2 = [“bar” => 2,“foo” => 1];
7
hash
key
value
type_info next
hash
key
value
type_info next
hash
key
value
type_info next
[0]
[1]
[2]
[3]
7
hash
key
value
type_info next
hash
key
value
type_info next
hash
key
value
type_info next
[0] = -1
[1] = -1
[2] = -1
[3] = -1
$a = [];numUsed = 0
7
hash
key
value = 42
LONG next = -1
hash
key
value
type_info next
hash
key
value
type_info next
[0] = -1
[1] = 0
[2] = -1
[3] = -1
“foo”
$a = [];$a[“foo”] = 42;
“foo”
numUsed = 1
7
hash
key
value = 42
LONG next = -1
hash
key
value = 24
LONG next = -1
hash
key
value
type_info next
[0] = -1
[1] = 0
[2] = -1
[3] = 1
“foo”
$a = [];$a[“foo”] = 42;$a[“bar”] = 24; “foo”
“bar”
“bar”
numUsed = 2
7
hash
key
value = 42
LONG next = 2
hash
key
value = 24
LONG next = -1
hash
key
value = 3.141
DOUBLE next = -1
[0] = -1
[1] = 0
[2] = -1
[3] = 1
“foo”
$a = [];$a[“foo”] = 42;$a[“bar”] = 24;$a[“xyz”] = 3.141;
“foo”
“bar”
“bar”
“xyz”
“xyz”
7
hash
key
value
UNDEF next = -1
hash
key
value = 24
LONG next = -1
hash
key
value = 3.141
DOUBLE next = -1
[0] = -1
[1] = 2
[2] = -1
[3] = 1
$a = [];$a[“foo”] = 42;$a[“bar”] = 24;$a[“xyz”] = 3.141;unset($a[“foo”]);
“bar”
“bar”
“xyz”
“xyz”
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
data / hash pointer
numUsed
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed
tableSize
tableMask = -tableSize
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed
tableSize
1010111010110110
tableMask = -tableSize
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed
tableSize
1010111010110110| 1111111111100000
tableMask = -tableSize
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed
tableSize
1010111010110110| 1111111111100000= 1111111111110110 = -10
tableMask = -tableSize
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed numElems
tableSize
nextFreeElement
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
tableMask
data / hash pointer
numUsed numElems
tableSize internalPtr
nextFreeElement
destructor
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
flags tableMask
data / hash pointer
numUsed numElems
tableSize internalPtr
nextFreeElement
destructor
flags applyCnt iterCnt
7
hash
key
value
type_info next
hash
key
value
type_info next
[-8] [-7]
[-6] [-5]
[-4] [-3]
[-2] [-1]
hash
data
refcount type_info
flags tableMask
data / hash pointer
numUsed numElems
tableSize internalPtr
nextFreeElement
destructor
flags applyCnt iterCnt
PACKEDetc.
7
hash
key
value
type_info next
hash
key
value
type_info next
data
refcount type_info
flags tableMask
data pointer
numUsed numElems
tableSize internalPtr
nextFreeElement
destructor
flags applyCnt iterCnt
PACKEDetc.
5
handle (ID)
handlers
zval value
…
read_prop()
write_prop()
…
object
object store bucket
actual object
5
handle (ID)
handlers
zval value
…
read_prop()
write_prop()
…
object
refcount
object store bucket
actual object
5
handle (ID)
handlers
zval value
…
read_prop()
write_prop()
…
object
dtor()
free_storage()
clone()
refcount
object store bucket
actual object
5
handle (ID)
handlers
zval value
…
read_prop()
write_prop()
…
object
dtor()
free_storage()
clone()
handlers
refcount
gc_root
object store bucket
actual object
5
handle (ID)
handlers
zval value
…
read_prop()
write_prop()
…
D V ac
object
dtor()
free_storage()
clone()
handlers
refcount
gc_root
object store bucket
actual object
5
object store bucketce
properties
properties_table
standard object
zend_class_entry
HashTable fordynamic properties
[0] (stores $prop1)
[1] (stores $prop2)
[2] (stores $prop3)
zval
zval
zval
5
object store bucketce
properties
properties_table
guards
standard object
zend_class_entry
HashTable fordynamic properties
[0] (stores $prop1)
[1] (stores $prop2)
[2] (stores $prop3)
zval
zval
zval
HashTable for__get etc. guards
5
object store bucketce
properties
properties_table
guards
custom extension
for internal object
standard object
zend_class_entry
HashTable fordynamic properties
[0] (stores $prop1)
[1] (stores $prop2)
[2] (stores $prop3)
zval
zval
zval
HashTable for__get etc. guards
7
zend_object *refcount type_info
handle
ce
handlers
properties
zend_class_entry
HashTable fordynamic properties
handler table
7
zend_object *refcount type_info
handle
ce
handlers
properties
zend_class_entry
HashTable fordynamic properties
handler table
object store
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
zend_class_entry
HashTable fordynamic properties$prop1 zval
$prop2 zval
$prop3 zval
handler table
object store
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
zend_class_entry
HashTable fordynamic properties
HashTable for__get etc. guards
guards zval
$prop1 zval
$prop2 zval
handler table
object store
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
zend_class_entry
HashTable fordynamic properties
HashTable for__get etc. guards
guards zval
$prop1 zval
$prop2 zval
handler table
object store
ext. for internal objects
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
zend_class_entry
HashTable fordynamic properties
HashTable for__get etc. guards
guards zval
$prop1 zval
$prop2 zval
handler table
object store
ext. for internal objects offset
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
guards zval
$prop1 zval
$prop2 zval
object store
ext. for internal objects
offset
…
handlers table
offset
7
zend_object *refcount type_info
handle
ce
handlers
properties
value
type_info
value
type_info
value
type_info
guards zval
$prop1 zval
$prop2 zval
object store
ext. for internal objects
offset
free()
dtor()
clone()
…
handlers table
offset
value = LONG(42)
refcount = 2$i
$k
$i = 42;$j = $i;$k = $i;$k++;
5
value = LONG(43)
refcount = 1
$j
copy-on-write (COW)
$i = 42;$j =& $i;$k =& $i;
7
$i value
REFERENCE
$j value
REFERENCE
$k value
REFERENCE
refcount = 3 type_info
value = 42
LONG
zend_reference
$a = range(0,1000000);
$r =& $a;
7
$a value
REFERENCE
$r value
REFERENCE refcount = 2 type_info
value
ARRAY
zend_reference
refcount = 1 type_info
…
zend_array
$a = range(0,1000000);
$r =& $a;$v = $a;
7
$a value
REFERENCE
$r value
REFERENCE
$v value
ARRAY
refcount = 2 type_info
value
ARRAY
zend_reference
refcount = 2 type_info
…
zend_array
PHP 5 PHP 7
zval 32 bytes 16 bytes
HashTable element 80 bytes 36 bytes (incl. zval)
HashTable 72 bytes 56 bytes
object 96 bytes 40 bytes
PHP 5 PHP 7
zval 32 bytes 16 bytes
HashTable element 80 bytes 36 bytes (incl. zval)
HashTable 72 bytes 56 bytes
object 96 bytes 40 bytes
fewer allocationsless indirection