Commit graph

312 commits

Author SHA1 Message Date
Dmitry Stogov
a066b809de Skip abstract methods 2021-12-27 15:28:46 +03: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
d56ec0a624 Merge branch 'PHP-8.1'
* PHP-8.1:
  Fixed bug #81607 (CE_CACHE allocation with concurrent access)
2021-11-17 18:25:00 +03:00
Dmitry Stogov
76548e5093 Fixed bug #81607 (CE_CACHE allocation with concurrent access) 2021-11-17 18:23:36 +03: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
Nikita Popov
6b2b4bb174 Remove unused scope argument 2021-10-19 17:31:13 +02:00
Nikita Popov
0a831423f7 Merge branch 'PHP-8.1'
* PHP-8.1:
  Restore CE_CACHE clear on persist
2021-10-05 10:33:46 +02:00
Nikita Popov
e8e4852ebb Restore CE_CACHE clear on persist
We still need to do this in case early binding succeeds and caches
the class. We could guard that by !in_compilation as well, but in
this case the previous cache clearing should be reliable, so
restore it.
2021-10-05 10:31:46 +02:00
Nikita Popov
d4368b88b6 Merge branch 'PHP-8.1'
* PHP-8.1:
  Don't populate CE_CACHE during compilation
2021-10-04 15:38:15 +02:00
Nikita Popov
ac70bb362e Don't populate CE_CACHE during compilation
It's possible for CE_CACHE slots to be populated during compilation
(e.g. due to an early binding attempt). When opcache then persists
the class, it clears the CE_CACHE slot for the class name as declared,
but not for different spellings (that only differ in case). As such,
a pointer to the old, non-persistent class entry may be retained.

Fix this by not populating CE_CACHE if in_compilation is set.

Closes GH-7542.
2021-10-04 15:38:01 +02: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
Dmitry Stogov
116fa65482 Fixed ZEND_MAP_PTR_KIND_PTR (it is not used) 2021-08-23 14:04:02 +03:00
Dmitry Stogov
476c333a8e Reorder updates to avoid race conditions 2021-08-23 11:47:30 +03:00
Nikita Popov
02b5660c0f Clear ce cache when persisting for file cache only
We should clear the ce cache before storing the interned string,
while we still have a reference to the original ce cache slot.
2021-08-12 10:34:21 +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
1bd6fafa2f Fix preloading of trait property attributes 2021-07-27 12:07:22 +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
Patrick Allaert
aff365871a Fixed some spaces used instead of tabs 2021-06-29 11:30:26 +02:00
Dmitry Stogov
bd98d84e57 Reorder conditions and always mark methods in SHM as ZEND_ACC_IMMUTABLE 2021-06-10 22:19:37 +03:00
Dmitry Stogov
2e93bb7a45 Fixed possible use after free 2021-05-12 17:21:39 +03:00
Dmitry Stogov
9f2389177e Fixed tracing JIT + preloading failures:
ext/opcache/tests/preload_003.phpt
ext/opcache/tests/preload_trait_multiple_fixup.phpt
ext/opcache/tests/preload_trait_static.phpt
2021-05-11 16:50:10 +03:00
Dmitry Stogov
cb0854bc53 JIT class methods only when class entry is completely persistent.
This fixes a number of test failures on low optimization levels.
(e.g. use after free in Zend/tests/bug54268.phpt and tests/classes/protected_001.phpt with opcache.jit=1204)
2021-05-11 15:49:35 +03: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
dd86987b2c
Replay warnings during inheritance (#6928)
Since 3e6b447979 it is again possible to have
warnings (deprecations) during inheritance, and more such functionality is
likely in the future. This is a problem, because such warnings will only be
shown on the first request if the opcache inheritance cache is used. This
currently causes test failures in --repeat builds.

Fix this by uplifting the error recording functionality from opcache to Zend,
and then using it to persist a warning trace in the inheritance cache, which
can then be used to replay the warnings on subsequent executions.
2021-04-29 16:37:53 +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
9a1da9f61f Don't use separate static variables in inherited methods
RFC: https://wiki.php.net/rfc/static_variable_inheritance

Closes GH-6719.
2021-04-28 17:08: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
Nikita Popov
fe9f4298b5 Fix class map ptr for parent type if interning disabled
As zend_update_parent_ce() only runs later, the parent reference
may still point to the original class entry rather than the
persisted one. Memory held by the original class entry may have
already been deallocated. Avoid use-after-free by explicitly
fetching the persisted parent CE.
2021-04-09 12:24:12 +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
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
4cff8c10a9 Simplify attribute persistence
For an inherited op_array, directly fetch the xlat entry, as we
do for everything else.
2021-03-17 11:52:45 +01:00
Dmitry Stogov
c732ab400a Change Zend Stream API to use zend_string* instead of char*.
This allows to eliminate re-calculation of string lenght and hash value.
See the detailed list of changes in UPGRADING.INTERNALS.
2021-03-16 20:31:36 +03:00
Dmitry Stogov
d02197853e Fixed assertion (ext/opcache/zend_persist.c:327: zend_accel_get_type_map_ptr: Assertion `ret > 2' failed) 2021-03-10 17:39:26 +03:00
Nikita Popov
97de8cfc71 Fix dynamic func def persist with preloading
If we find an existing serialization of the op_array, of course
we also need to actually make use of it...
2021-03-04 16:15:05 +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
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
15f713bd85 Persist class name before methods, because it may be used insted of "self" 2021-02-15 12:33:53 +03:00
Dmitry Stogov
dcf389228c Avoid useless SHM data duplication 2021-02-11 16:51:08 +03:00
Dmitry Stogov
a8f6d44c1c Fixed map_ptr slot sharing for trait/self 2021-02-10 17:59:11 +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
Dmitry Stogov
b3bbb8fe3b Mark classes cached by opcache by ZEND_ACC_CACHED flag and prevent useless copying and desrpoying of immutable data. 2021-01-19 11:55:09 +03:00
Nikita Popov
3e01f5afb1 Replace zend_bool uses with bool
We're starting to see a mix between uses of zend_bool and bool.
Replace all usages with the standard bool type everywhere.

Of course, zend_bool is retained as an alias.
2021-01-15 12:33:06 +01:00
Dmitry Stogov
1a44599dee Always use CG(arena) for unin type lists 2021-01-12 16:33:38 +03:00
Nikita Popov
7794925ba4 Assert that references are not persisted
There should not be any need to persist references, and it's unlikely
that persisting a reference will behave correctly at runtime, because
we don't have a concept of an immutable reference.
2020-11-04 14:51:44 +01:00
Nikita Popov
14c42c6961 Fix persisting property info table with internal parent
If the property info comes from an internal parent, we won't have
an xlat entry for it. Leave it alone in that case.
2020-11-03 11:30:44 +01:00
Nikita Popov
7620ea1580 Don't intern compiled_filename
For php-ast interning the file name is an effective memory leak,
see php-ast#134.

I don't think there's any reason to do this. At some point this
was needed due to bugs in the interned string mechanism that
caused issues if the string was later interned, e.g. through a
__FILE__ reference. These issues have since been resolved.

In conjunction with the filenames_table removal in c4016ecd44
this means that filenames now need to be refcounted like normal
strings. In particular the filename reference in op_arrays and CEs
are refcounted.
2020-09-03 12:31:23 +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