From Maciej:
The garbage collector in JavaScriptCore has been improved quite a bit from the earliest versions. But much greater efficiency can be achieved with a garbage collector that uses a generational algorithm, so we don't have to mark all the objects every time we garbage collect. This should make JavaScript run significantly faster.
I'm setting up this page as a project page to track the progress of the generational collector for JavaScript Core. I intend to use it to keep design notes, and hold discussions about the various ways in which such a collector could be implemented. I'm also looking for volunteers who want to get involved. If you're interested, and you know your way around C/C++ pretty well, please get in touch with Bkocik. This should turn out to be a very interesting, challenging, and rewarding project with high visibility. If you're looking to make a big impact on WebKit, this is a good way.
There are couple of questions that needs to be answered before start of generational GC development:
- What is an average number of objects that needs to be collected?
- What is an average size of memory pool?
I do not know particular numbers (they depend on particular implementation/schema) but suspect that there is a margin where simple copying GC (a.k.a. single generation GC) is even faster than generational one. At least less code needed to run. I suspect that the gain you can get with gGC on average Web page (with Ajax) will be (very) low.
I think that the very first thing that needs to be done is an implementation of bytecoded VM instead of interpretation of AST used by KJS. That can really improve speed including speed of GC.
TIScript engine implementation can be used as a possible prototype of compiler and VM. TIScript source is here: http://code.google.com/p/tiscript/, language specification is here: http://www.terrainformatica.com/wiki/tiscript:start
TIScript VM is using stack VM with single register that is simple yet effective enough.
Andrew Fedoniouk / terrainformatica.com
As far as I understand the situation, the main impetus for a generational collector is to reduce the pauses that occur when collection is triggered. Most studies have shown that a generational collector at the very least reduces the average pause length of collections, even if it may slightly decrease throughput in some cases. A web browser, at least on an intuitive level, seems like a situation where the generational hypothesis is resoundingly true, so I don't think there is a large potential issue with a loss of throughput.
I think that the first attempt should be a simple two generation copying collector. Since we don't want to rely on any MMU magic (which is sometimes unpredictable and slow in userspace) the best system for tracking intergenerational pointers would probably be card marking, where the cards are some small fraction of a full page. The copying nature of the collector would require references from non-JS objects to have an extra level of indirection, but I don't think this will really affect performance too much.
The possible switch to a bytecode VM from the current interpreter is orthogonal to the choice of garbage collector. As it stands, the JS Core interpreter is very competitive with the speed of other JavaScript implementations.
Cameron Zwarich / cwzwarich at uwaterloo.ca
How about making less garbage? If there is less garbage there will be less garbage to collect, right? A seemingly simple change would be to make each StringNode cache (and protect) the JSValue* that execute() returns. In my normal browsing, there seemed to be a reduction of about 12% in the number of allocates (and cells eventually collected).
John Moe
Closures and garbage collector
Consider the snippet set out below. Is the argument iniValue of the function CreateClosure part of the closure? Will iniValue preserve the initial arrays from being garbage collected even when the value is changed via setValue? Is Javascript VM able to determine which arguments must be a part of the closure object or it just consist of all arguments regardless of whether they are used within some internal function or not?
var closure1 = CreateClosure(["c","1"," ","i","n","i","t","i","a","l"," ","v","a","l","u","e"]);
var closure2 = CreateClosure(["c","2"," ","i","n","i","t","i","a","l"," ","v","a","l","u","e"]);
closure1();
closure2();
closure1.setValue(["c","1"," ","n","e","w"," ","v","a","l","u","e"])();
closure2.setValue(["c","2"," ","n","e","w"," ","v","a","l","u","e"])();
function CreateClosure(iniValue)
{
var closure = function()
{
window.console.log(closure.value.join(""));
}
closure.value = iniValue;
closure.setValue = function(value)
{
this.value = value;
return this;
}
closure.getValue = function()
{
return this.value;
}
return closure;
}
Best regards,
Aleck Agakhan