On Apr 6, 2012, at 5:16 PM, Stas Malyshev <smalys...@sugarcrm.com> 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