Closed tmbrbr closed 2 years ago
Tentative plan for a fix is to Template / Subclass StringTaint so that implementations need to provide memory management callbacks.
The JS implementation would assign memory only on the JS Heap, so will be removed with the rest of the String. A vanilla std implementation can still be used which uses new
and delete
operators as necessary.
Challenge will be how to port a std::vector
into a SpiderMonkey JS object.
Some hopefully helpful links:
A summary of the problem so far:
The nursery collection is done here: https://github.com/SAP/project-foxhound/blob/main/js/src/gc/Nursery.cpp#L1221
The problem being that objects are deleted by overwriting memory in blocks, so no finalize is called. This is not an issue normally, as the nursery also keeps track of all buffers allocated etc. and just deletes everything.
An alternative workaround would be to do an extra scan of objects remaining in the nursery and delete their taint information.
More info here: https://hacks.mozilla.org/2014/09/generational-garbage-collection-in-firefox/
The StringTaint implementation is leaking memory, for example in SpiderMonkey.
The following JavaScript sample:
when run with valgrind (using suggestions from here):
gives the following output:
The reason for the leak is that StringTaint stores a vector of TaintRanges in a pointer which is managed by StringTaint. Actually, the caller has to ensure that
clear()
is called before the StringTaint is destroyed. In most cases this happens when a StringType is destroyed by the SpiderMonkey VM (via the finalize method, but is not happening in all instances.Attaching a debugged and watching the location of one of the created (but not finalized) Strings, shows that the JS Cell is only altered when the program terminates. Here's the Stack:
Where it looks like instead of clearing up objects individually, the memory is simply overwritten (I guess this is quicker). For regular Strings this is not a problem as any char buffers associated to the object will also be stored in the SpiderMonkey Heap somewhere and also be deleted.
In the case of the TaintRange vector (which lives outside the JS Heap), the pointer is overwritten and therefore memory lost.
Note: The motivation for using regular memory management rather than the SpiderMonkey one is to make the Taint code portable between SpiderMonkey and the other String representations in Firefox, such as DOMStrings and nsStrings.