Hi,

This is the 2nd of two exchanges that occurred off-list that Stas and I
would like to put back on-list.

Greg
===
Stanislav Malyshev wrote:
> > Hi!
> >
>> >> Basically, the patch does 2 things
>> >>
>> >> 1) resolution order is changed to:
>> >>
>> >> foo.php:
>> >> $a = new foo();
>> >> a) does namespace::foo class exist?
>> >> b) try to autoload namespace::foo
>> >> c) try to locate internal class ::foo
>> >>
>> >> 2) if internal class ::foo is found, then cache this information
so that
>> >> if another reference to the foo class occurs in foo.php, resolution
>> >> short circuits to:
>> >> a) use internal class ::foo
>> >>
>> >> This second point is why the slowdown went from ridiculous to slight.
> >
> > OK, now I understand better what it does, thanks. Do I understand
> > right that the caching is in runtime, when the class access opcode is
> > executed (since you couldn't autoload in compile time)? If so, how
> > long the cache entry is kept there? I.e. if I have execution path that
> > goes to file A, then B, then A again, then C, then B, etc. and then
> > unroll the stack back - do I store all results for second entrance
> > into A? Is it per-op-array (since we don't have per-file data
> > structure AFAIK)? What happens if include path (or autoloader)
> > changes, so that the class name that could not be loaded before can be
> > loaded now - e.g. application adds plugin definitions, etc. - will it
> > be ensured that autoloading is never attempted again for the same
> > class? What happens if somebody loads that namespace::foo class
> > manually (with require) - will the old resolution hold or the new one
> > apply?
> >
> > Also I note that even if the cache stores all resolutions for all
> > internal classes times all namespaces, it will still require at least
> > one exhaustive autoload search per internal class per op-array - or
> > per file, if you somehow find a way to store cache per-file in
> > runtime, and these can not be eliminated with bytecode caching, unlike
> > all other filesystem accesses.
Hi,

The caching is at runtime.  Basically, it's in executor_globals, and so
is not linked to any opcode array (I couldn't figure out any other
globally accessible storage location).  It works like an associative
array.  If file X.php loads XMLReader in namespace namespacename, it
creates this entry:

array(
    'X.php\0namespacename::XMLReader' => {class entry for XMLReader}
);

So that the next time we reach X.php and the XMLReader class, it sees
this entry, and does not attempt autoload.  As for your questions about
include_path/autoload, I had not added this to the patch, but the easy
solution is to clean the hash on include_path change, or autoload
change.  I assume this code would break with the patch:

sneakyreader.php:
<?php
namespace foo;
class XMLReader {}
?>

main.php:
<?php
namespace foo;
$a = new XMLReader; // loads ::XMLReader
include 'sneakyreader.php';
$a = new XMLReader; // still loads ::XMLReader
?>

Whereas with the current behavior, it would instead instantiate
foo::XMLReader on the second access.  However, this is definitely a wtf
situation - the exact same looking line of code would load a different
class name entirely depending on what was included.

The cache does not eliminate the first autoload per-file.

I'm sure there are other issues to work out, but this should give a
better idea of what I am trying to do.

As for your question of whether to simply error out if foo::XMLReader
doesn't exist (in the main.php example above), this also would be
acceptable for classes, but not for functions, as the ratio of
user-defined to internal functions in any source code example is 1:many,
many.  However, we don't autoload functions or constants, so load ordr
is an absolute, much as it was for classes in PHP 4 before autoload was
introduced.

It is not an easy problem to solve, but we do need to solve it prior to
the next release.  Should we take this back on-list?

Greg


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

Reply via email to