Re: Persistent zvals
On Apr 6, 2012, at 5:16 PM, Stas Malyshev <[email protected]> wrote:
Hi!
From what I've gathered thus far, it is impossible to do without copying the
non-persistent memory into persistent memory, and then back again. I'm
assuming this is because all the memory associated with PHP variables use
emalloc, which places it onto a stack that is disposed of at the end of the
request.
The stack part is wrong, emalloc does not use stack, but the general
sense of it is correct - all memory allocated by emalloc is freed at the
end of the request, so anything you would want to preserve would have to
be copied to some other memory area.
How is memory tracked with emalloc? From my observations anything
created with emalloc, with or without a zval wrapper, is freed at the
end of the request. Things created with pemalloc, which seems to be a
wrapper of malloc, isn't thrown away.
I saw some references (off the top if my head - on my phone) to
something like G(mm_stack)->_malloc(...), which is called by emalloc.
Could you briefly explain how it does work or point be to a link that
does? Up until now I've been pouring over the source code - and there
is a lot, tracing down macro after macro.
2 - Modify the Zend engine to flag objects/zvals as persistent so they
aren¹t thrown away until the process ends.
The problem with that is that these variables can contain references to
other variables and other things (like class in object, etc.) that will
be freed, so the data will point to freed memory. Unless the variable is
a simple scalar or you do not allow associating it with any other
variables in any way you would have this problem. If it's a simple
scalar, you can do better by using existing caches. Not allowing
associations with other variables means there's not much reason for this
thing to actually be a PHP variable.
From what I've seen this is because the zvals, the values inside, the
object bucket, etc... is all created by emalloc. Correct me if I'm
wrong, but even if i could persist the zval (wrapper) the value inside
would be freed unless both the zval and the value were created with
pemalloc (alias of malloc). It goes a step further with the objects
because a zend_object is just a handle ID (pointing to a spot in the
bucket) and a pointer to object handlers.
I've been able to do it somewhat with string zvals, but objects are a
different story (given that a zval contains a handle index referring an
entry in a bucket). The "goal", at least with objects, is the objects
doesn't destruct until the end of the process. With copying memory it looks
With objects you have a problem - do you also mean to keep the class?
What about the methods code? If you intend to keep all this in memory -
and remember you'd also have to guard all of it so no "local" variable
gets anywhere into any of object's properties, or sub-values of these
properties - I'm not sure you'd do better than serializing.
At this point I feel light a mad scientist. I'm hoping to gain some insight
on how this might be done properly with PHP 5.3/5.4 (or just 5.4) - even if
it involves modifying the Zend engine. Have you guys had any recent
discussions about doing this?
Doing it is much harder than you think, since all structures in Zend
Engine are assumed to be temporary and you'd need to copy a lot of stuff
to make your object work. I wouldn't really advise it.
Don't get me wrong - I totally get it. Trying to copy the zvals, the
value inside, and the object out of the bucket, and then the
descendants is not a good solution. It would probably be buggy at best
and not much better than serialization. I'd like to avoid copying
memory if possible. A flag on the zval would be ideal.
With the continued assumption that memory structures are temporary
something like this will never be feasible. In order for something
like this to work (at least from my understanding. - I'm probably
totally wrong) values inside a zval would have to be created with
malloc and the life cycle of that object would have to be determined
by the wrapping zval. A zval would have a persistent flag and a
recount the value inside would be released when the recount reaches
zero or at the end of the request if the persistent flag is zero....
But this is something totally different than it is now.
Luke
--
Stanislav Malyshev, Software Architect
SugarCRM: http://www.sugarcrm.com/
(408)454-6900 ext. 227
Thread (20 messages)