Skip to content

Commit f516936

Browse files
committed
Document rc separation
1 parent aa059ed commit f516936

File tree

1 file changed

+30
-19
lines changed

1 file changed

+30
-19
lines changed

docs/source/core/data-structures/reference-counting.rst

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,17 @@
55
In languages like C, when you need memory for storing data for an indefinite period of time or in a
66
large amount, you call ``malloc`` and ``free`` to acquire and release blocks of memory of some size.
77
This sounds simple on the surface but turns out to be quite tricky, mainly because the data may not
8-
be freed for as long as it is used, anywhere in the program. Sometimes, this makes it unclear who is
8+
be freed for as long as it is used anywhere in the program. Sometimes this makes it unclear who is
99
responsible for freeing the memory, and when to do so. Failure to handle this correctly may result
10-
in use-after-free, double-free, and memory leaks.
10+
in a use-after-free, double-free, or memory leak.
1111

12-
Very rarely do you have to think about memory management when working in PHP. The engine takes care
13-
of this for you by tracking which values are no longer needed. It does this by assigning a reference
14-
count to each value, often abbreviated as refcount or RC. Whenever a reference to a value is passed
15-
to somebody else, its reference count is increased to indicate the value is now used by another
16-
party. When the party no longer needs the value, it is responsible for decreasing the reference
17-
count. Once the reference count reaches zero, we know the value is no longer needed anywhere in the
18-
program, and that it may be freed.
12+
In PHP you usually do not need to think about memory management. The engine takes care of allocating
13+
and freeing memory for you by tracking which values are no longer needed. It does this by assigning
14+
a reference count to each allocated value, often abbreviated as refcount or RC. Whenever a reference
15+
to a value is passed somewhere else, its reference count is increased to indicate the value is now
16+
used by another party. When the party no longer needs the value, it is responsible for decreasing
17+
the reference count. Once the reference count reaches zero, we know the value is no longer needed
18+
anywhere, and that it may be freed.
1919

2020
.. code:: php
2121
@@ -33,9 +33,9 @@ Reference counting is needed for types that store auxiliary data, which are the
3333
- Resources
3434

3535
These are either reference types (objects, references and resources) or they are large types that
36-
don't fit in a single ``zend_value`` directly (strings, arrays). More simple types either don't
37-
store a value at all (``null``, ``false``, ``true``) or their value is small enough to fit directly
38-
in ``zend_value`` and copied when passed somewhere else (``int``, ``float``).
36+
don't fit in a single ``zend_value`` directly (strings, arrays). Simpler types either don't store a
37+
value at all (``null``, ``false``, ``true``) or their value is small enough to fit directly in
38+
``zend_value`` (``int``, ``float``).
3939

4040
All of the reference counted types share a common initial struct sequence.
4141

@@ -58,10 +58,6 @@ All of the reference counted types share a common initial struct sequence.
5858
// ...
5959
};
6060
61-
This explains the ``zval.value.counted`` union member in the ``zval`` struct we saw in the ``zval``
62-
chapter. It refers to the initial ``gc`` field of any reference counted type, in case we don't care
63-
about which concrete type we're dealing with.
64-
6561
The ``zend_refcounted_h`` struct is simple. It contains the reference count, and a ``type_info``
6662
field that repeats some of the type information that is also stored in the ``zval``, for situations
6763
where we're not dealing with a ``zval`` directly. It also stores some additional fields, described
@@ -135,10 +131,25 @@ naming is not always consistent.
135131
Separation
136132
************
137133

138-
..
139-
::
134+
PHP has value and reference types. Reference types are types that are shared through a reference, a
135+
"pointer" to the value, rather than the value itself. Modifying such a value in one place changes it
136+
for all of its observers. For example, writing to a property changes the property in every place the
137+
object is referenced. Value types, on the other hand, are copied when passed to another party.
138+
Modifying the original value does not affect the copy, and vice versa.
139+
140+
In PHP, arrays and strings are value types. Since they are also reference counted types, this
141+
requires some special care when modifying values. In particular, we need to make sure that modifying
142+
the value is not observable from other places. Modifying a value with RC 1 is unproblematic, since
143+
we are the values sole owner. However, if the value has a reference count of >1, we need to create a
144+
fresh copy before modifying it. This process is called separation or CoW (copy on write).
145+
146+
.. code:: php
140147
141-
_TODO
148+
$a = [1, 2, 3]; // RC 1
149+
$b = $a; // RC 2
150+
$b[] = 4; // Separation, $a RC 1, $b RC 1
151+
var_dump($a); // [1, 2, 3]
152+
var_dump($b); // [1, 2, 3, 4]
142153
143154
***********************************
144155
Immutable reference counted types

0 commit comments

Comments
 (0)