Hi!

> In most cases we avoid IS_UNDEF checks, verifying the most probable expected 
> types first.

But that's for something like ADD, not for property fetches, so I'm not
sure I understand how properties fit there yet. Does the optimization
also track the variable after fetching?

In any case, to use this without any UNDEF/NULL checks, you need to be
absolutely sure the value is always initialized to the right type. I.e.
if you have a class like:

class Point {
        public int $x;
        public int $y;
}

Then you need to request the following:

- Always require the default. Otherwise, even in ctor, you could use $x
in expression before it is initialized and assume it is long where it is
in fact null. For many classes, the default would be completely
arbitrary (e.g. 0 is not always a natural default).

- Somehow handle unserialization in order to ensure what is put into $x
is always int. Moreover, unserialization may involved __wakeup which
sets up some properties, and before those properties are set up, how do
we ensure they have the right types without checking? Unserialize data
can contain anything, we had enough trouble with this unserializing
internal objects.

- Ensure that no extension manually creates objects without properly
initializing the typed variables. Extensions can easily create objects
right now and they can put anything in the object's hashes, can we trust
that every extension does the right thing?

The cost of getting any of these wrong may be high - it's not just
getting weird conversion, if the engine assumes something is LONG or
STRING without checking, it can be memory corruption or even RCE if
we're particularly unlucky.

So I am very skeptical right now about the possibility of making
optimizations based on using property type without checking based on
just declared type in the class.

Additionally, if we *do* allow the possibility of NULL/UNDEF, the
performance loss would be quite minimal - we could still do
specialization based on assumed type, but then just insert something like:

if (UNEXPECTED(NULL_TYPE(op1)) {
  op1 = &null_as_long;
}

for types that have natural default for longs, or something like:

if (UNEXPECTED(NULL_TYPE(op1)) {
        zend_error("Undefined value where object is expected");
}

if we expected object. The cost of one branch that is almost never taken
should be quite minimal, and we avoid a lot of trouble on the way.

-- 
Stas Malyshev
smalys...@gmail.com

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to