On 2011-04-06, at 10:06 PM, chevalma@iro.umontreal.ca wrote:
Please explain what you mean by "more compatible with our system". It is not clear to me what you mean. Also, I don't recall that we agreed on anything concerning the design of the loader. I originally agreed with your argument that it wouldn't be possible to patch the executable code, but I later explained that this would not be a problem because we can use the OS assembler to patch the addresses when the file is loaded.
And I explained that the OS linker won't be able to call hash consing functions,
The linker shouldn't have to call hash consing functions at run time. When the image is dumped, a table of all the strings can be constructed (using hash-consing, but at "image dump time"). That hash-consed string table can then be dumped to the image. That way there will be no need to reconstruct the table when the image starts running. This would be a waste of execution time.
Just to be clear, I am trying to capitalize on opportunities to do some of the work once and for all when the image is dumped. Including:
- not having to copy the code to a new zone (by using executable binary format) - not having to patch the code (by using the assembler and linker) - not having to reconstruct the initial string table (by computing it at image dump time)
Wouldn't it be nice if Tachyon was already doing useful stuff (such as executing/compiling/optimizing the user's JS code) in as little as 3 to 5 milliseconds after startup? That is definitely possible with the directly executable image format I am proposing.
and that we may need to re-patch the machine code during execution (e.g.: after garbage collection).
We can arrange things so that re-patching the machine code is not needed for garbage-collection. We can distinguish "permanent objects" which are allocated forever and whose address does not change, from non-permanent objects (which are allocated during the execution of the program and can be reclaimed). A tag in an object's header, or address ranges can be used to mark objects as permanent. The code in an image would be a set of permanent objects. If permanent objects only point to permanent objects, the garbage-collector can also avoid to scan them to find the live objects. This can save a lot of work for the garbage-collector (it does not have to scan the code in the image, which for some applications can be most of the "data").
Re-patching will be needed for inline-caching and related techniques. But that's not a problem because we can always use the mprotect system call to mark those pages with permission read-write-execute. At least there won't be two copies of the code (one in the image and one in the heap) and no copying/patching of the code and construction of the string table at run time.
The reason why the approach I propose is "more compatible with our system" is that it fits with the way code is compiled and linked at run-time. Storing code in the .text segment is what is traditionally done for statically compiled programs. It's outside of our control and requires special handling, since this code is potentially not movable, not freeable, not rewritable.
One applications where startup time is important is when you have a web server processing requests by starting up a new process running the desired program (which is a realistic situation for our "server-side" use of Tachyon).
People haven't been doing that since the CGI scripting day. Every modern server-side scripting system (RoR, Django, PHP, etc.) ships with a module that runs persistently in the web server.
And that technique has a bunch of problems that come with it... including security issues, uncontrolled space consumption (leaks from one execution to the next), and load balancing. The reason such modules are needed is to circumvent the slow startup times of some language implementations. That's what I want to avoid with a clean efficient design!
I would appreciate it if you trusted me on this issue.
It is not a matter of trust. I am putting forward some technical arguments and measurements which show the advantages of the directly executable image format. Do you dispute my technical arguments?
I intend for the implementation to be simple and efficient while fitting with the current design. If somehow, someday, we find that our loading time is hugely burdened and that it's worth complicating our implementation to try and scrape off 15ms, it can be changed down the road.
Some days you make the argument that "we can change it down the road", and other days "lets do it right the first time so that we don't have to do it again". Please make up your mind. You can't have it both ways.
In the garbage-collector I want to be able to explore the benefit of having permanent objects to reduce the garbage-collection time. Also, copying the code from the image to a new zone doubles the virtual memory footprint of the code. I want to avoid this extra burden on the memory system which will decrease the effectiveness of the garbage-collector. Moreover, I am also concerned about mobile platforms which have much less memory and CPU speed (the loading time will be roughly 10 times longer on ARM so a 50 ms load time becomes a 0.5 second load time, which is noticeable and annoying to the user).
In the meantime, initializing Tachyon after the machine code is loaded and linked is going to take at least an order of magnitude more time than the loading/linking itself... And this will still make for a very reasonable total loading time.
Don't justify an inefficiency on the basis of the existence of another bigger inefficiency! This kind of reasoning quickly turns into an acceptance of a system's sluggishness. It takes only one inefficient subsystem to ruin the overall performance.
Initializing Tachyon should not take much time. If it does we need to profile the code and figure out why. Currently we haven't done any of that and the quality of the generated machine code is poor. Once that is fixed, the loading time will be dominant.
Marc