Commit graph

195 commits

Author SHA1 Message Date
Dmitry Stogov
310b5283eb Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Reset inheritance_cache pointer of zend_class_entry upon serialization (#12401)
2023-10-11 09:57:35 +03:00
Sergei Turchanov
90f2e7607a
Reset inheritance_cache pointer of zend_class_entry upon serialization (#12401)
to opcache filecache. Usually, when a class is being loaded, a dependency
tracking is performed after the call to zend_file_cache_script_store.
But sometimes, when opcache cache is empty and there are many simultaneous
outstanding requests for compilation, some classes do have their
inheritance_cache initialized before the call to zend_file_cache_script_store,
and in that case this pointer is serialized as-is. And when such a class
is loaded from opcache filecache this pointer also loaded as-is, and now
it points to some random location in memory. This causes segfaults occuring
when traversing inheritance_cache of such classes.

We need to reset inheritance_cache pointer of zend_class_entry
upon serialization. This should have been done anyway since it is a sensible
strategy to sanitize any memory pointer upon serialization (either by calling
SERIALIZE_x macros or setting to NULL or any other deterministic value).
2023-10-11 09:57:18 +03:00
Ilija Tovilo
f2328302b6
Merge branch 'PHP-8.1' into PHP-8.2
* PHP-8.1:
  Check if restart is pending before trying to lock SHM
2023-07-31 20:00:49 +02:00
Mikhail Galanin
3e9792f4a2
Check if restart is pending before trying to lock SHM
This reduces lock contention when Opcache restart is scheduled
but not yet started.

Closes GH-11805
2023-07-31 20:00:31 +02:00
Arnaud Le Blanc
ea1287b015
Log the cause of error when opcache cannot write to file cache (#9258) 2022-09-03 11:23:43 +02:00
Ilija Tovilo
ddc0b490f7
Allow arbitrary const expressions in backed enums
Closes GH-7821
Closes GH-8190
Closes GH-8418
2022-06-12 22:56:05 +02:00
Max Kellermann
04a4864b65
ext/opcache: merge redundant code and "bool" refactoring (#8237)
* ext/opcache/ZendAccelerator: make check_persistent_script_access() static

* ext/opcache/ZendAccelerator: convert "int" to "bool"

* ext/opcache/zend_file_cache: convert "int" to "bool"

* ext/opcache: use true/false for zend_persistent_script.corrupted

* ext/opcache/ZendAccelerator: move duplicate code to zend_accel_discard_script()

* ext/opcache/ZendAccelerator: convert accel_deactivate_now() to function

Simplify the #iddef ZEND_WIN32.

* ext/opcache/zend_file_cache: simplify iovec initializer

* ext/opcache/zend_file_cache: add local zend_string* variables

Eliminates lots of redundant casts and avoids reloading the variable
from RAM into registers.

* ext/opcache/zend_file_cache: use ZSTR_VAL()

* ext/opcache/zend_file_cache: move code to zend_file_cache_script_write()

This eliminates duplicate error handling code.
2022-03-24 15:03:53 +01:00
Max Kellermann
63281763bf ext/opcache/zend_shared_alloc: add zend_shared_alloc_aligned()
Eliminate some duplicate code.
2022-03-20 20:42:14 +01:00
Nikita Popov
4543cd32ae Remove JMPZNZ opcode
While JMPZNZ can avoid execution of a separate JMP opcode in some
cases, it also prevents smart branch optimization, so creating
JMPZNZ may actually have a negative effect. It also adds additional
complexity for optimizations.

Drop JMPZNZ in favor of JMPZ+JMP or JMPNZ+JMP.

Closes GH-7857.
2022-01-10 22:07:10 +01:00
Tyson Andre
024d5f4b63 Cache method overrides of ArrayAccess in zend_class_entry
Previously, code such as subclasses of SplFixedArray would check for method
overrides when instantiating the objects.

This optimization was mentioned as a followup to GH-6552
2021-12-04 11:35:38 -05:00
Dmitry Stogov
90b7bde615 Use more compact representation for packed arrays.
- for packed arrays we store just an array of zvals without keys.
- the elements of packed array are accessible throuf as ht->arPacked[i]
  instead of ht->arData[i]
- in addition to general ZEND_HASH_FOREACH_* macros, we introduced similar
  familied for packed (ZEND_HASH_PACKED_FORECH_*) and real hashes
  (ZEND_HASH_MAP_FOREACH_*)
- introduced an additional family of macros to access elements of array
  (packed or real hashes) ZEND_ARRAY_ELEMET_SIZE, ZEND_ARRAY_ELEMET_EX,
  ZEND_ARRAY_ELEMET, ZEND_ARRAY_NEXT_ELEMENT, ZEND_ARRAY_PREV_ELEMENT
- zend_hash_minmax() prototype was changed to compare only values

Because of smaller data set, this patch may show performance improvement
on some apps and benchmarks that use packed arrays. (~1% on PHP-Parser)

TODO:
    - sapi/phpdbg needs special support for packed arrays (WATCH_ON_BUCKET).
    - zend_hash_sort_ex() may require converting packed arrays to hash.
2021-11-03 15:18:26 +03:00
Dmitry Stogov
ddaf64b56c Avoid non-immutable map_ptr indirection 2021-10-14 12:16:18 +03:00
Nikita Popov
c19977d054 Fix delayed early binding with optimization
It's possible for delayed early binding opcodes to get optimized
away if they are "unreachable". However, we still need to attempt
early binding for them. (In some cases we also corrupt the early
binding list outright during optimization, which is how I got here.)

Fix this by storing information about delayed early binding
independently of DECLARE_CLASS_DELAYED opcodes, so early binding is
performed even after the opcode has been dropped.
2021-09-29 18:00:20 +02:00
Nikita Popov
ba8e5d336b Merge branch 'PHP-8.0'
* PHP-8.0:
  Test file_cache prime shm + use file combination
  Fix repeated file cache unserialization of zval string
2021-08-18 12:39:47 +02:00
Nikita Popov
de7ba3e737 Fix repeated file cache unserialization of zval string
The IS_UNSERIALIZED check here does not work if the string is
interned (serialized with file_cache_only=0) but unserialization
happens with file_cache_only=1. In this case the unserializde
string will be in the str area after mem, which is not included
in the script size, and which is also not accessible at this
point without threading through more information. Work around
the problem by checking for the serialized representation instead.
2021-08-18 12:38:27 +02:00
Nikita Popov
e86a0a905d Assert that file cache does not contain references 2021-08-17 17:13:19 +02:00
Nikita Popov
315f40942b
Always use CE_CACHE, remove TYPE_HAS_CE (#7336)
Currently, CE_CACHE on strings is only used with opcache interned strings. This
patch extends usage to non-opcache interned strings as well. This means that
most type strings can now make use of CE_CACHE even if opcache is not loaded,
which allows us to remove TYPE_HAS_CE kind, and fix some discrepancies
depending on whether a type stores a resolved or non-resolved name.

There are two cases where CE_CACHE will not be used:

 * When opcache is not used and a permanent interned string (that is not an
   internal class name) is used as a type name during the request. In this case
   we can't allocate a map_ptr index for the permanent string, as it would be
   not be in the permanent map_ptr index space.
 * When opcache is used but the script is not cached (e.g. eval'd code or
   opcache full). If opcache is used, we can't allocate additional map_ptr
   indexes at runtime, because they may conflict with indexes allocated by
   opcache.

In these two cases we would end up not using CE caching for property types
(argument/return types still have the separate cache slot).
2021-08-11 10:28:52 +02:00
Nikita Popov
5e997ec3ce
Remove special self/parent handling in get_class_name_map_ptr() (#7330)
zend_accel_get_class_name_map_ptr() for "self" and "parent" will
currently try to determine which class these refer to, and then
initialize the CE_CACHE on those strings.

However, this shouldn't be necessary: We already initialize
CE_CACHE on all class declaration names, so it should be covered
through that already.
2021-08-10 10:29:20 +02:00
Nikita Popov
3eb97a4566 Always use separate static_members_table
When running without opcache, static_members_table is shared with
default_static_members_table. This is visible in reflection output,
because ReflectionProperty::getDefaultValue() will return the
current value, rather than the default value.

Address this by never sharing the table, which matches the behavior
we already see under opcache.

Fixes bug #80821.

Closes GH-7299.
2021-07-23 09:29:32 +02:00
Joe Watkins
570d9b63e9
Not serializable flag permeation 2021-07-20 12:28:35 +02:00
KsaR
01b3fc03c3
Update http->https in license (#6945)
1. Update: http://www.php.net/license/3_01.txt to https, as there is anyway server header "Location:" to https.
2. Update few license 3.0 to 3.01 as 3.0 states "php 5.1.1, 4.1.1, and earlier".
3. In some license comments is "at through the world-wide-web" while most is without "at", so deleted.
4. fixed indentation in some files before |
2021-05-06 12:16:35 +02:00
Nikita Popov
e8e7c04a3a Use common struct to store error information
This is needed by both fibers and opcache (and GH-6903 also uses it),
so make it a common structure that can be used by any functionality
storing warnings/errors.
2021-04-29 11:50:54 +02:00
Nikita Popov
f1ce44d1cb Fix static variables in main script with file cache
If the script will be cached in SHM (!corrupted), then we cannot
allocate the static variables on the arena. Instead do the same
thing we do during normal persistence and allocate a map ptr slot.
2021-04-15 16:37:28 +02:00
Nikita Popov
bd3ba5465b Revert "Don't allocate temporary file cache memory on arena"
This reverts commit 4440ac3ed6.

This fix wasn't correct, as we do retain the arena-allocation
for the file cache only case. This will need some other way to
reconcile both modes.
2021-04-10 12:46:22 +02:00
Nikita Popov
4440ac3ed6 Don't allocate temporary file cache memory on arena
During unserialization, static_variables and runtime_cache may be
allocated on the arena, and then later freed when the checkpoint
is released.

As we're only doing a single large allocation here, simply move
this to the normal allocator, so there is no interference with
other arena allocations.
2021-04-09 17:11:50 +02:00
Nikita Popov
e0e19fd955 Fix file cache
We should only access xlat if this is called from persist, not
when it is called from file cache.
2021-04-09 16:52:18 +02:00
Dmitry Stogov
d8e4fbae62 Fast Class Cache
This is generalization of idea, that was previously usesd for caching
resolution of class_entries in zend_type. Now very similar mechanizm is
used for general zend_string into zend_class_entry resolution.

Interned zend_string with IS_STR_CLASS_NAME_MAP_PTR GC_FLAG uses its
refcount to adress corresponding zend_class_entry cache slot.
The refcount keeps an offset to this slot from CG(map_ptr_base).
Flag may be checked by ZSTR_HAS_CE_CACHE(str), cache slot may be read by
ZSTR_GET_CE_CACHE(str) and set by ZSTR_SET_CE_CACHE(str, ce).
2021-04-08 23:37:40 +03:00
Dmitry Stogov
8ed8cf86a9 Use zend_string* instead of char* 2021-03-22 14:56:16 +03:00
Ilija Tovilo
269c8dac1d
Implement enums
RFC: https://wiki.php.net/rfc/enumerations

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>

Closes GH-6489.
2021-03-17 19:08:03 +01:00
Nikita Popov
709e45d89b Avoid unnecessary static_variables persistence
static_variables should be treated the same way as all other
op_array components nowadays (only static_variables_ptr is
special). There's no need to persist/serialize it is separately
per shared op_array.
2021-03-17 12:20:58 +01:00
Nikita Popov
47a2e5c785 Reference dynamic functions through dynamic_defs
Currently, dynamically declared functions and closures are inserted
into the function table under a runtime definition key, and then later
possibly renamed. When opcache is not used and a file containing a
closure is repeatedly included, this leads to a very large memory leak,
as the no longer needed closure declarations will never be freed
(https://bugs.php.net/bug.php?id=76982).

With this patch, dynamic functions are instead stored in a
dynamic_func_defs member on the op_array, which opcodes reference
by index. When the parent op_array is destroyed, the dynamic_func_defs
it contains are also destroyed (unless they are stilled used elsewhere,
e.g. because they have been bound, or are used by a live closure). This
resolves the fundamental part of the leak, though doesn't completely
fix it yet due to some arena allocations.

The main non-obvious change here is to static variable handling:
We can't destroy static_variables_ptr in destroy_op_array, as e.g.
that would clear the static variables in a dynamic function when
the op_array containing it is destroyed. Static variable destruction
is separated out for this reason (we already do static variable
destruction separately for normal functions, so we only need to
handle main scripts).

Closes GH-5595.
2021-03-01 11:35:54 +01:00
Nikita Popov
23afc62080 Allow pointer to end of memory in IS_UNSERIALIZED()
We already use <= for IS_SERIALIZED(), but the same general
problem can also occur for IS_UNSERIALIZED(). We don't seem to
hit this in practice prior to GH-5595 though.
2021-02-24 11:46:35 +01:00
Nikita Popov
5d160e309e Fix static variable behavior with inheritance
When a method is inherited, the static variables will now always
use the initial values, rather than the values at the time of
inheritance. As such, behavior no longer depends on whether
inheritance happens before or after a method has been called.

This is implemented by always keeping static_variables as the
original values, and static_variables_ptr as the modified copy.

Closes GH-6705.
2021-02-18 11:18:19 +01:00
Dmitry Stogov
b113f7e88e Unserialize op_array->scope before passing to zend_file_cache_unserialize_type().
Don't use scope of closures.
2021-02-10 23:55:59 +03:00
Dmitry Stogov
6aea64c444 Reuse single map_ptr slot for indentical class names 2021-02-10 15:22:09 +03:00
Dmitry Stogov
4b79dba932 Added Inheritance Cache.
This is a new transparent technology that eliminates overhead of PHP class inheritance.

PHP  classes are compiled and cached (by opcahce) separately, however their "linking" was done at run-time - on each request. The process of "linking" may involve a number of compatibility checks and borrowing methods/properties/constants form parent and traits. This takes significant time, but the result is the same on each request.

Inheritance Cache performs "linking" for unique set of all the depending classes (parent, interfaces, traits, property types, method types involved into compatibility checks) once and stores result in opcache shared memory. As a part of the this patch, I removed limitations for immutable classes (unresolved constants, typed properties and covariant type checks). So now all classes stored in opcache are "immutable". They may be lazily loaded into process memory, if necessary, but this usually occurs just once (on first linking).

The patch shows 8% improvement on Symphony "Hello World" app.
2021-02-09 22:53:57 +03:00
Sammy Kaye Powers
12306728c5
Add system ID entropy API
The `zend_system_id` is a (true global) system ID that fingerprints a process state. When extensions add engine hooks during MINIT/startup, entropy is added the system ID for each hook. This allows extensions to identify that changes have been made to the engine since the last PHP process restart.

Closes GH-5871
2020-09-18 14:26:44 -07:00
Nikita Popov
75baa729f5 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #79917
2020-08-11 14:59:04 +02:00
Nikita Popov
4609ded082 Fixed bug #79917
op_arrays can be shared on two levels: Either the op_array is
completely shared, or it is distinct but shares all members
(apart from static_variables).

The the op_array is distinct, we need to make sure to properly
initialize the MAP_PTR structures.
2020-08-11 14:58:54 +02:00
Nikita Popov
643145b59d Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug #79930
  Fix iov_base pointer type for illumos
  Backport bless_tests.php changes from PHP 8
2020-08-05 15:44:04 +02:00
Nikita Popov
9d9fa32fe5 Merge branch 'PHP-7.3' into PHP-7.4
* PHP-7.3:
  Fix iov_base pointer type for illumos
2020-08-05 15:18:03 +02:00
David Carlier
12db8b90a7 Fix iov_base pointer type for illumos
These systems has two versions of the iovec interface dependent on
compiler flags passed, the legacy version causing little build issue.

Closes GH-5939.
2020-08-05 15:17:51 +02:00
Nikita Popov
d92229d8c7 Implement named parameters
From an engine perspective, named parameters mainly add three
concepts:

 * The SEND_* opcodes now accept a CONST op2, which is the
   argument name. For now, it is looked up by linear scan and
   runtime cached.
 * This may leave UNDEF arguments on the stack. To avoid having
   to deal with them in other places, a CHECK_UNDEF_ARGS opcode
   is used to either replace them with defaults, or error.
 * For variadic functions, EX(extra_named_params) are collected
   and need to be freed based on ZEND_CALL_HAS_EXTRA_NAMED_PARAMS.

RFC: https://wiki.php.net/rfc/named_params

Closes GH-5357.
2020-07-31 15:53:36 +02:00
Ilija Tovilo
9bf119832d
Implement nullsafe ?-> operator
RFC: https://wiki.php.net/rfc/nullsafe_operator

Closes GH-5619.

Co-authored-by: Nikita Popov <nikita.ppv@gmail.com>
2020-07-24 10:05:03 +02:00
Ilija Tovilo
9fa1d13301
Implement match expression
RFC: https://wiki.php.net/rfc/match_expression_v2

Closes GH-5371.
2020-07-09 23:52:17 +02:00
Nikita Popov
1314ccbf8c Cache __unserialize() instead of unserialize()
We should use these cache slots for the new object serialization
mechanism rather than the old one.
2020-06-26 10:54:40 +02:00
Dmitry Stogov
bb3d4456ee Change GC_COLLECTABLE flag into GC_NOT_COLLECTABLE to simplify GC_MAY_LEAK() check 2020-06-15 14:26:22 +03:00
Benjamin Eberlei
a7908c2d11 Add Attributes
Co-authored-by: Martin Schröder <m.schroeder2007@gmail.com>
2020-06-04 18:19:49 +02:00
Nikita Popov
0a74da385d Add support for replaying warnings in opcache
If opcache.record_warnings is enabled, opcache will record
compilation warnings and replay them when the file is included
again. The primary use case I have in mind for this is automated
testing of the opcache file cache.

This resolves bug #76535.
2020-05-20 11:20:21 +02:00
Nikita Popov
1b1d313275 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fix static property indirections in file cache
  Don't require rc=1 for function static variables
2020-05-20 11:13:35 +02:00