Commit graph

440 commits

Author SHA1 Message Date
Dmitry Stogov
b1b79c74fb Fix memory leak
This fixes oss-fuzz #47088
2022-05-11 11:43:01 +03:00
Bob Weinand
a44d99fe23 Merge branch 'PHP-8.0' into PHP-8.1 2022-03-07 22:06:58 +01:00
Tim Düsterhus
0d7e10c1a9 Fix memory leak of function attribute hash table (#8070)
==109253== 280 (56 direct, 224 indirect) bytes in 1 blocks are definitely lost in loss record 4 of 4
    ==109253==    at 0x483B7F3: malloc (in /usr/lib/x86_64-linux-gnu/valgrind/vgpreload_memcheck-amd64-linux.so)
    ==109253==    by 0x6D9FA2: __zend_malloc (zend_alloc.c:3068)
    ==109253==    by 0x745138: zend_add_attribute (zend_attributes.c:226)
    ==109253==    by 0x6680D1: zend_add_parameter_attribute (zend_attributes.h:102)
    ==109253==    by 0x66B787: zm_startup_zend_test (test.c:478)
    ==109253==    by 0x7224CD: zend_startup_module_ex (zend_API.c:2202)
    ==109253==    by 0x72252C: zend_startup_module_zval (zend_API.c:2217)
    ==109253==    by 0x734288: zend_hash_apply (zend_hash.c:2011)
    ==109253==    by 0x722C30: zend_startup_modules (zend_API.c:2328)
    ==109253==    by 0x67409B: php_module_startup (main.c:2256)
    ==109253==    by 0x88EDDE: php_cli_startup (php_cli.c:409)
    ==109253==    by 0x890F61: main (php_cli.c:1334)
2022-03-07 22:05:40 +01:00
Nikita Popov
44e5d25300 Fix inheritance of class constants if mutable data used
Class constants from parents should always be directly reused,
rather than re-evaluated as a separate copy. Previously this used
to happen automatically, as we'd just inherit the class constant
entry from the parent class. With mutable data there may now be
a separate copy of the constant, so we need to use that copy
when updating constants. Otherwise we may evaluate the same
constant multiple times.

Closes GH-7658.
2021-11-17 12:23:47 +01:00
Nikita Popov
1039852fec Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Fix COPY_TMP live range construction with optimization
2021-11-11 10:36:45 +01:00
Nikita Popov
8c4a7f20f5 Fix COPY_TMP live range construction with optimization
The use may be optimized away, leaving us only with the free use.
Also fix off-by-one error in the other optimization case.
2021-11-11 10:35:34 +01:00
Nikita Popov
8360e9d6d1 Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Fix COPY_TMP live range construction after optimization
2021-10-05 11:28:41 +02:00
Nikita Popov
bbd3f714d7 Fix COPY_TMP live range construction after optimization
If we optimize the FREE away, we should switch to constructing
a normal live range, rather than a split live range.

Fixes oss-fuzz #39548.
2021-10-05 11:28:16 +02:00
Nikita Popov
7879544022 Merge branch 'PHP-8.0' into PHP-8.1
* PHP-8.0:
  Handle SWITCH_STRING with optimized away FREE
2021-09-16 11:33:08 +02:00
Nikita Popov
7257e7e5aa Handle SWITCH_STRING with optimized away FREE
This can happen in degenerate cases where we know that the
SWITCH_STRING argument is not refcounted. We should be treating it
in the same way as SWITCH_LONG here.
2021-09-16 11:31:06 +02:00
Nikita Popov
e011952576
Preload unlinked classes, remove preload autoload (#7311)
Currently, classes that can't be linked get moved back into the original script
and are not preloaded. As such classes may be referenced from functions that
did get preloaded, there is a preload autoload mechanism to load them at
runtime.

Since PHP 8.1, we can safely preload unlinked classes, which will then go
through usual lazy loading. This means that we no longer need the preload
autoload mechanism. However, we need to be careful not to modify any hash
table buckets in-place, and should create new buckets for lazy loaded classes.
2021-07-28 14:27:58 +02:00
Nikita Popov
a374230c15 Add support for internal enums
This adds support for internal enums with the same basic approach
as userland enums. Enum values are stored as CONSTANT_AST and
objects created during constant updating at runtime. This means
that we need to use mutable_data for internal enums.

This just adds basic support and APIs, it does not include the
stubs integration from #7212.

Closes GH-7302.
2021-07-27 09:19:14 +02:00
Nikita Popov
36d2dd087a Remove redundant static_members/mutable_data cleanup
static_members, mutable_data and static vars in methods are cleaned
up during an earlier shutdown phase (because this has to happen
before we destroy the object store). There is no need to repeat
this cleanup when destroying the classes.
2021-07-23 13:01:40 +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
Nikita Popov
79071d5e3e
Don't duplicate internal prop info (#6929)
Userland property infos are no longer duplicated since PHP 7.4, when we
stopped setting SHADOW flags on inherited private properties. Stop duplicating
internal property infos as well.

This requires switching class destruction to work in reverse order, as child
classes may be reusing structures from parent classes, and as such should be
destroyed first.
2021-04-29 20:31:24 +02:00
George Peter Banyard
5caaf40b43
Introduce pseudo-keyword ZEND_FALLTHROUGH
And use it instead of comments
2021-04-07 00:46:29 +01: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
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
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
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
George Peter Banyard
fa8d9b1183 Improve type declarations for Zend APIs
Voidification of Zend API which always succeeded
Use bool argument types instead of int for boolean arguments
Use bool return type for functions which return true/false (1/0)
Use zend_result return type for functions which return SUCCESS/FAILURE as they don't follow normal boolean semantics

Closes GH-6002
2020-08-28 15:41:27 +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
Christoph M. Becker
92c4b06513 Use ZEND_UNREACHABLE() instead of ZEND_ASSERT(0)
Instead of marking unreachable code with `ZEND_ASSERT(0)`, we introduce
`ZEND_UNREACHABLE()`, so that MSVC which does not consider `assert(0)`
to mark unreachable code does no longer trigger C4715[1] warnings in
debug builds.  This may be useful for other compilers as well.

[1] <https://docs.microsoft.com/de-de/cpp/error-messages/compiler-warnings/compiler-warning-level-1-c4715?view=vs-2019>
2020-06-16 18:39:09 +02:00
Nikita Popov
d3eeeb6882 Don't leak attributes on internal classes
Also add zend_hash_release() API to complement zend_array_release(),
because the latter is specific to non-persistent zval arrays.
2020-06-05 10:29:49 +02:00
Benjamin Eberlei
a7908c2d11 Add Attributes
Co-authored-by: Martin Schröder <m.schroeder2007@gmail.com>
2020-06-04 18:19:49 +02:00
George Peter Banyard
826a745671 Fix [-Wjump-misses-init] in generated zend_opcode.c 2020-04-18 14:52:49 +02:00
Nikita Popov
53efa1b0c6 Store aliased name of trait method
Currently, trait methods are aliased will continue to use the
original function name. In a few places in the codebase, we will
try to look up the actual method name instead. However, this does
not work if an aliased method is used indirectly
(https://bugs.php.net/bug.php?id=69180).

I think it would be better to instead actually change the method
name to the alias. This is in principle easy: We have to allow
function_name to be changed even if op array is otherwise shared
(similar to static_variables). This means we need to addref/release
the function_name separately, but I don't think there is a
performance concern here (especially as everything is usually
interned).

There is a bit of complication in opcache, where we need to make
sure that the function name is released the correct number of times
(interning may overwrite the name in the original op_array, but we
need to release it as many times as the op_array is shared).

Fixes bug #69180.
Fixes bug #74939.
Closes GH-5226.
2020-03-03 11:55:48 +01:00
Nikita Popov
5a90392c6a Use EX_NUM_TO_VAR() in more places
Not sure why I missed these before.
2020-02-27 13:13:24 +01:00
Nikita Popov
1949a26aac Remove more null arithmetic UB
Introduce an EX_NUM_TO_VAR macro to mirror EX_VAR_TO_NUM and
replace usages of the ZEND_CALL_VAR_NUM(NULL) pattern.
2020-02-27 12:54:48 +01:00
Nikita Popov
38e27625ea Merge branch 'PHP-7.4'
* PHP-7.4:
  Fix live range calculation for FE_FETCH
2020-01-30 14:24:28 +01:00
Nikita Popov
be7eab3202 Fix live range calculation for FE_FETCH
Op2 is def here, not a use, so treat it accordingly.
2020-01-30 14:23:46 +01:00
Nikita Popov
bd1977282c Use zend_type inside type lists
Instead of having a completely independent encoding for type list
entries. This is going to use more memory, but I'm not particularly
concerned about that, as type unions that contain multiple classes
should be uncommon. On the other hand, this allows us to treat
top-level types and types inside lists mostly the same.

A new ZEND_TYPE_FOREACH macros allows to transparently treat list
and non-list types the same way. I'm not using it everywhere it could be
used for now, just the places that seemed most obvious.

Of course, this will make any future type system changes much simpler,
as it will not be necessary to duplicate all logic two times.
2020-01-17 09:37:54 +01:00
Nikita Popov
999e32b65a Implement union types
According to RFC: https://wiki.php.net/rfc/union_types_v2

The type representation now makes use of both the pointer payload
and the type mask at the same time. Additionall, zend_type_list is
introduced as a new kind of pointer payload, which is used to store
multiple class types. Each of the class types is a tagged pointer,
which may be either a class name or class entry. The latter is only
used for typed properties, while arguments/returns will instead use
cache slots. A type list can contain a mix of both names and CEs at
the same time, as not all classes may be resolvable.

One thing this is missing is support for union types in arginfo
and stubs, which I want to handle separately.

I've also dropped the special object code from the JIT implementation
for now -- I plan to add this back in a different form at a later time.
For now I did not want to include non-trivial JIT changes together
with large functional changes.

Another possible piece of follow-up work is to implement "iterable"
as an internal alias for "array|Traversable". I believe this will
eliminate quite a few special-cases that had to be implemented.

Closes GH-4838.
2019-11-08 15:15:48 +01:00
Nikita Popov
d927b745d6 Merge branch 'PHP-7.4'
* PHP-7.4:
  Fix static prop cleanup for dl'ed internal classes
2019-10-21 12:17:43 +02:00
Nikita Popov
3d55386aa8 Fix static prop cleanup for dl'ed internal classes 2019-10-21 12:17:38 +02:00
Nikita Popov
ade97c207c Merge branch 'PHP-7.4' 2019-08-26 16:12:47 +02:00
Nikita Popov
e2b49d6c45 Don't use needs_live_range hook for "special" live ranges
In particular we were disgarding SILENCE live ranges in opcache,
because we decided that a MAY_BE_LONG type does not need a live
range.
2019-08-26 16:12:03 +02:00
Nikita Popov
51ea7fc477 Merge branch 'PHP-7.4' 2019-08-23 17:01:49 +02:00
Nikita Popov
8807889ac2 Fix arginfo leak when using disabled_classes
Also remove the hack where scope is set to NULL in order to make
free_internal_arg_info work. Instead explicitly call it for class
methods.

This fixes the asan build for Zend/tests/bug77494.phpt.
2019-08-23 17:00:59 +02:00
Dmitry Stogov
5ac3580b9b Merge branch 'PHP-7.4'
* PHP-7.4:
  ZEND_DECLARE_ANON_CLASS doesn't need to skip anything now. It's immediatelly followed by ZEND_NEW.
2019-07-19 10:10:50 +03:00
Dmitry Stogov
b065fbde19 ZEND_DECLARE_ANON_CLASS doesn't need to skip anything now. It's immediatelly followed by ZEND_NEW. 2019-07-19 10:09:26 +03:00
Dmitry Stogov
1b5b8175af Merge branch 'PHP-7.4'
* PHP-7.4:
  Replace ZEND_ASSIGN_ADD (and others) by ZEND_ASSIGN_OP, ZEND_ASSIGN_DIM_OP, ZEND_ASSGIN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP
2019-07-05 12:16:30 +03:00
Dmitry Stogov
48ca5a1e17 Replace ZEND_ASSIGN_ADD (and others) by ZEND_ASSIGN_OP, ZEND_ASSIGN_DIM_OP, ZEND_ASSGIN_OBJ_OP and ZEND_ASSIGN_STATIC_PROP_OP 2019-07-05 12:03:25 +03:00
Nikita Popov
aa2320b274 Merge branch 'PHP-7.4' 2019-06-28 16:39:57 +02:00
Nikita Popov
3698303540 Fix arginfo leak in disable_functions
Arginfo is allocated if types are used, we need to free it.
2019-06-28 16:38:46 +02:00
Dmitry Stogov
e18c60cd8d Merge branch 'PHP-7.4'
* PHP-7.4:
  Fixed bug 78175 (Preloading must store default values of static variables and properties)
2019-06-24 20:34:05 +03:00