# Patch for opcode caches

- Thread: https://externals.io/message/36141
- Original archive: https://news-web.php.net/php.internals/36141
- Started by Dmitry Stogov on 2008-03-14T16:08:18+00:00
- Messages: 8
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #36141 — Dmitry Stogov — 2008-03-14T16:08:18+00:00

URL: https://externals.io/message/36141#36141

> I do not want to remove early binding. In fact I always 
> wanted to have early binding as much as possible. Because 
> that is faster and makes compiler caches easier. So why slow 
> down stuff? A Compiler cache wants everythign as static as 
> possible which means a compiler cache wants early binding. 
> This is also faster. So what are you proposing here?

As I already explained, early binding may not work for cached code,
because of cross file dependencies.
My patch allows to delay early binding from file-compile-time to
file-load-from-cache-time.

Thanks. Dmitry.

---

## #36142 — Marcus Boerger — 2008-03-14T16:32:51+00:00

URL: https://externals.io/message/36141#36142 · In reply to: #36141

Hello Dmitry,

Friday, March 14, 2008, 5:08:18 PM, you wrote:

> > […]

> As I already explained, early binding may not work for cached code,
> because of cross file dependencies.
> My patch allows to delay early binding from file-compile-time to
> file-load-from-cache-time.

But that means we are compiling inheritance when a file is loaded form
the cache. The goal should be to compiling inheritance when writing to
the opcode cache file. All we achieve here is a slow down. If there is
something that makes this required than at least we need to warn the user
about the slow code. I Think what we need to do is deprecating class and
namespace use in non main blocks as well as include and require in non
main blocks. And if there is no such case than everything can be bound
early which is the fast state we should aim for.

Best regards,
 Marcus

---

## #36143 — Stanislav Malyshev — 2008-03-14T16:51:49+00:00

URL: https://externals.io/message/36141#36143 · In reply to: #36142

> But that means we are compiling inheritance when a file is loaded form
> the cache. The goal should be to compiling inheritance when writing to
> the opcode cache file. All we achieve here is a slow down. If there is

You can not do that. You do not know that until runtime.

> something that makes this required than at least we need to warn the user
> about the slow code. I Think what we need to do is deprecating class and

It won't be slow. It would be much faster (in some cases 10x faster). 
This specific assembly of instructions might be slower in some cases, 
but the code altogether will be faster. That's the idea of the opcode 
caches.

> namespace use in non main blocks as well as include and require in non
> main blocks. And if there is no such case than everything can be bound
> early which is the fast state we should aim for.

We do not need to deprecate anything, and inheritance can not be bound 
before parent class is known, which in the case of bytecode cache means 
- not before the file is loaded from the cache. That's exactly what this 
patch enables. It does not change performance characteristics of neither 
cached not non-cached code, it just makes it much simpler and working in 
all cases.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #36144 — Marcus Boerger — 2008-03-14T17:23:55+00:00

URL: https://externals.io/message/36141#36144 · In reply to: #36143

Hello Stanislav,

Friday, March 14, 2008, 5:51:49 PM, you wrote:

> > […]

> You can not do that. You do not know that until runtime.

> > […]

> It won't be slow. It would be much faster (in some cases 10x faster). 
> This specific assembly of instructions might be slower in some cases, 
> but the code altogether will be faster. That's the idea of the opcode 
> caches.

> > […]

Lemme just think, doing inheritance at compile time before we send the stuff
to an opcode cache can be slower then? How is that possible? After all late
binding means we do it at run time. And no matter how much faster we can do
it. It will always be slower than doing the same thing only once.

> We do not need to deprecate anything, and inheritance can not be bound 
> before parent class is known, which in the case of bytecode cache means 
> - not before the file is loaded from the cache. That's exactly what this 
> patch enables. It does not change performance characteristics of neither 
> cached not non-cached code, it just makes it much simpler and working in 
> all cases.

Inheritance cannot be done before the parent class is known. We still need
to do the prototype checks even if we assume the class is there and insert
a virtual class as parent somehow.

Best regards,
 Marcus

---

## #36146 — Rasmus Lerdorf — 2008-03-14T18:10:59+00:00

URL: https://externals.io/message/36141#36146 · In reply to: #36144

Marcus Boerger wrote:
> Hello Stanislav,
> 
> Friday, March 14, 2008, 5:51:49 PM, you wrote:
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> 
> > […]
> 
> Lemme just think, doing inheritance at compile time before we send the stuff
> to an opcode cache can be slower then? How is that possible? After all late
> binding means we do it at run time. And no matter how much faster we can do
> it. It will always be slower than doing the same thing only once.
> 
> > […]
> 
> Inheritance cannot be done before the parent class is known. We still need
> to do the prototype checks even if we assume the class is there and insert
> a virtual class as parent somehow.

I don't actually see early binding as being much of a problem, the real 
problem is when the same class is both early and late bound.  If you 
consistently always bind early or always bind late, opcode caches should 
be quite happy to let you do that.  But if you mix the two, things get 
chaotic and the problem becomes intractable.  We went through all this 
in APC a couple of years ago.  My initial, somewhat naiive attempt at 
fixing it:

   http://news.php.net/php.pecl.cvs/4288

That obviously wasn't enough to fix it, so essentially we end up simply 
detecting the scenario and not doing early binding for classes that are 
detected to also be bound late:

   http://pecl.php.net/bugs/bug.php?id=5314

-Rasmus

---

## #36147 — Marcus Boerger — 2008-03-14T18:28:13+00:00

URL: https://externals.io/message/36141#36147

Hello Stanislav,

Friday, March 14, 2008, 6:48:52 PM, you wrote:

> Hi!

> > […]

> I'm taking this off-list because it doesn't seem to go any direction it 
> can be useful for people to read.

Hmm, so other people must not read what we discuss, that does not work.

> Repeating again: it can not be done "only once". Not with opcode caches 
> present and bound entities living in separate file. This thing is not 
> possible. If you do not believe it - try to implement it and see.

That is my point. It can be done. The reason to delay inheritance is that we
can have a conditional statement around a class definition. If we detect
classes that do not have conditionals around them, then we can bind them
early. It is as easy as that. So instead of making the language more
dynamic and even removing a chance of having inheritance dones early where
possible we should work on making the desired case - eraly binding - as
easy as possible.

marcus

---

## #36148 — Stanislav Malyshev — 2008-03-14T19:11:20+00:00

URL: https://externals.io/message/36141#36148 · In reply to: #36146

> I don't actually see early binding as being much of a problem, the real 
> problem is when the same class is both early and late bound.  If you 
> consistently always bind early or always bind late, opcode caches should 
> be quite happy to let you do that.  But if you mix the two, things get 

That's what we try to do in this patch - to make cache able to change 
the binding mode.
-- 
Stanislav Malyshev, Zend Software Architect
stas@zend.com   http://www.zend.com/
(408)253-8829   MSN: stas@zend.com

---

## #36149 — Xuefer — 2008-03-15T08:21:04+00:00

URL: https://externals.io/message/36141#36149 · In reply to: #36146

>  I don't actually see early binding as being much of a problem, the real
>  problem is when the same class is both early and late bound.  If you
>  consistently always bind early or always bind late, opcode caches should
>  be quite happy to let you do that.  But if you mix the two, things get
>  chaotic and the problem becomes intractable.  We went through all this
>  in APC a couple of years ago.  My initial, somewhat naiive attempt at
i'm not sure why i can't reproduce it years ago with apc enabled and i
reproduce it with a complex script later.

a1.php
class a { function aMethod() { echo __FILE__; } }
a2.php
class a { function aMethod() { echo __FILE__; } }
child.php
class child extends a { }

main1.php which is requested first
include "a1.php";
include "child.php";
$child = new child()
$child->aMethod(); // aMethod() from a1.php, but what if i update
a1.php after child.php is cached?

main2.php which is requested later
include "a2.php";
include "child.php";
$child = new child();
$child->aMethod(); // aMethod() from a1.php because of early binding
is done before cache? or from a2.php?

with and without opcode cacher, what is echo'ed if you requests main1
first and main2 later?

with the delayed early binding, php behavior exactly the same with
opcode cachers enabled or disabled
imho, with delayed early binding, every class is binded once when
there is no opcode cacher, and opcode cacher can even decide to call
bind api before cache.
looks like we can always the delay the binding unless we want binary
back compatbility for 3rd party modules? correct me if i'm wrong
