Nikita Popov [Mon, 4 Nov 2019 10:24:32 +0000 (11:24 +0100)]
Remove dead code related to inherits props in reflection
Public/protected properties defined in parent classes will be
inherited in the child -- there is no need to explicitly try to
walk up the chain and look them up.
Nikita Popov [Mon, 4 Nov 2019 10:01:56 +0000 (11:01 +0100)]
Fixed bug #78774
The string held by the zend_type may be released if the property
type gets resolved to a CE. I initially wanted to fix this by
storing a zend_type* instead (so the property type resolution
propagates to the ReflectionType), but decided against this in
light of upcoming union types support, where we also need to
represent parts of the union, and will not have a single zend_type*
we can reference.
We actually have to check `$num_points` instead of `2*count($points)`,
because the latter may be greater than the former, but not all elements
of `$points` are guaranteed to be used. This allowed to pass arrays
with excess elements to draw polygons with less than three vertices.
While the current implementation of `gdImagePolygon()` and friends
would allow us to draw monogons and digons, we don't allow that
anymore, because the respective drawing primitives work slightly
different (e.g. drawing lines support anti-aliasing, but drawing
general polygons does not).
To minimize the BC break, we do not fix this longstanding issue for PHP
7, but target PHP 8 only.
This is more liberal then before, where that parameter (if given) had
to be IS_LONG, while now it would be converted to int according to weak
typing rules. This is, however, more what a developer would expect.
Since `zend_parse_parameters()` throws now, there is no reason to
explicitly call `zend_parse_parameters_throw()` anymore, and since both
have actually the same implementation, we redefine the latter as macro.
Nikita Popov [Thu, 31 Oct 2019 10:27:53 +0000 (11:27 +0100)]
Remove configure checks for supported instruction sets
These were checking whether the instruction set is supported by
the host CPU, however they were only used to condition on whether
this instruction set is targeted at all. It would still use dynamic
dispatch (e.g. based on ifunc resolvers) to select the actual
implementation. Whether the target is guaranteed to support the
instruction set without dispatch is determined based on pre-defined
macros like __SSE2__.
This removes the configure-time builtin cpu checks to remove
confusion. Additionally this allows targeting an architecture that
is newer than the host architecture.
Nikita Popov [Wed, 30 Oct 2019 12:15:05 +0000 (13:15 +0100)]
Fix bug #77930: Remove mmap limit
First, the limitation already doesn't trigger if you copy the whole
file (i.e. use copy() or stream_copy_to_stream() and don't specify
a length). This happens because length will be 0 at the time of the
check and only later calculated based on the file size. This means
that we're already completely blowing the length limit for what is
likely the most common case, and it doesn't seem like anyone complained
about that.
Second, the premise of the code comment ("to avoid runaway swapping")
seems incorrect to me. Because this performs a file-backed non-private
mmap, no swap backing is needed for the mapping. Concerns over "memory
usage" are also misplaced, as this is a virtual mapping.
We're currently splitting up large writes into 8K size chunks, which
adversely affects I/O performance in some cases. Splitting up writes
doesn't make a lot of sense, as we already must have a backing buffer,
so there is no memory/performance tradeoff to be made here.
This change disables the write chunking at the stream layer, but
retains the current retry loop for partial writes. In particular
network writes will typically only write part of the data for large
writes, so we need to keep the retry loop to preserve backwards
compatibility.
If issues due to this change turn up, chunking should be reintroduced
at lower levels where it is needed to avoid issues for specific streams,
rather than unnecessarily enforcing it for all streams.
Tyson Andre [Fri, 25 Oct 2019 23:57:39 +0000 (19:57 -0400)]
Optimize creation of empty arrays in json_decode
Use the shared empty array from ZVAL_EMPTY_ARRAY
For code that created an 10 arrays of 100000 empty arrays
(has the same result with `$assoc=true` and `{}`)
- This is the worst-case comparison, but I'd expect 0-length arrays to be fairly
common in regular data for json_decode
- The parser implementation was using function pointers so that third party
extension developers could reuse the json parser for their own
data structures, etc. (I think).
This PR is meant to let those third party extensions continue working
without changes.
Before this patch: In 0.126 seconds: added 97.99 MiB
After this patch: In 0.096 seconds: added 41.99 MiB
```php
<?php
$json = '[' . str_repeat('[],', 100000) . "null]";
$start_memory = memory_get_usage();
$start_time = microtime(true);
$result = [];
for ($i = 0; $i < 10; $i++) {
$result[] = json_decode($json);
}
$end_memory = memory_get_usage();
$end_time = microtime(true);
// Before this patch: In 0.126 seconds: added 97.99 MiB
// After this patch: In 0.096 seconds: added 41.99 MiB
printf("In %.3f seconds: added %.2f MiB\n", $end_time - $start_time, ($end_memory - $start_memory)/1000000);
// For objects
$json = '[' . str_repeat('{},', 100000) . "null]";
$start_memory = memory_get_usage();
$start_time = microtime(true);
for ($i = 0; $i < 10; $i++) {
$result[] = json_decode($json, true);
}
$end_memory = memory_get_usage();
$end_time = microtime(true);
// Before this patch: In 0.126 seconds: added 97.99 MiB
// After this patch: In 0.096 seconds: added 41.99 MiB
printf("In %.3f seconds: added %.2f MiB (objects decoded as arrays) \n", $end_time - $start_time, ($end_memory - $start_memory)/1000000);
```
Nikita Popov [Mon, 7 Oct 2019 11:04:06 +0000 (13:04 +0200)]
Warn on strtr(["" => "x"])
Previously:
* If only ["" => "x"] was present, the original string was returned
without warning.
* If both ["" => "x"] and at least one more element was present,
false was returned without warning.
New behavior:
* Ignore "" keys in the replacement array (and perform any remaining
replacement).
* Throw a warning indicating that an empty string replacement has
been ignored.
Tyson Andre [Tue, 29 Oct 2019 23:48:28 +0000 (19:48 -0400)]
Update documentation/comment for GH-4860
Fix folding for the new helper method.
Clarify comment in UPGRADING:
The performance on associative arrays would also improve,
as long as no offsets were unset (no gaps).
Packed arrays can have gaps.
Nikita Popov [Wed, 13 Feb 2019 10:37:32 +0000 (11:37 +0100)]
Don't check $this existence in object opcodes
We are now guaranteed that $this always exists inside methods, as
well as insides closures (if they use $this at all).
This removes checks for $this existence from the individual object
opcodes. Instead ZEND_FETCH_THIS is used in the cases where $this
is not guaranteed to exist, which is mainly the pseudo-main scope.
Allow to call XMLReader::open() and ::XML() statically
The implementation of `XMLReader::open()` and `XMLReader::XML()` still
supports calling the methods statically and non-statically. However,
as of PHP 8.0.0, calling these methods statically is not allowed,
because they are not declared as static methods. Since we consider it
to be cleaner to call these methods statically, but had deprecated to
call them statically, we properly support both variants.
We implement support for static and non-static calls by overloading, so
that non-static calls have access to the `$this` pointer.
Implement #78270: Support __vectorcall convention with FFI
To work around the limitation of the current rudimentary vectorcall
support in our patched libffi, we forbid yet unsupported declarations,
i.e. float/double parameters at certain positions (SIMD vector types
and HVA types are not supported anyway).
When getting the properties of a DatePeriod instance we have to retain
the proper classes, and when restoring a DatePeriod instance we have to
cater to DateTimeImmutable instances as well.