[profiler] Redesign buffer flushing and method reporting.
authorAlex Rønne Petersen <alexrp@xamarin.com>
Mon, 9 Mar 2015 18:03:44 +0000 (19:03 +0100)
committerAlex Rønne Petersen <alexrp@xamarin.com>
Tue, 17 Mar 2015 15:35:45 +0000 (16:35 +0100)
commitae58dce8223b80c3b66f4b79d343d8f985607884
tree0414111dbc0e0fdc5e6e0c06dba371ac2ce5f799
parent481bd0d83d18332169806e7bd531bcf143990972
[profiler] Redesign buffer flushing and method reporting.

The main goal of this change is to ensure that all methods have a `TYPE_JIT`
event emitted in the stream before they are referenced in other events. Before
this change, `TYPE_JIT` events could arrive out of order or not be emitted at
all because of generic sharing.

We now use a separate thread for writing log buffers to the output file.
Whenever a method is referenced in a TLS log buffer, we add it to a TLS list of
methods. When we ship the TLS log buffer off to the writer thread, we also send
the TLS list of methods. The writer thread first goes over all the methods and,
if some of them haven't had a `TYPE_JIT` event emitted yet, emits them to a
temporary buffer which is flushed just before flushing the main log buffer.

This approach ensures that `TYPE_JIT` events will *always* come before the
events that reference them.

Bookkeeping of which methods have been emitted to the output stream is done in
a global, concurrent hash table. Before a thread adds a method to its TLS list
of methods, it checks if the method is in the hash table. If it is, we know
that the method has already been emitted to the output stream, so it isn't
added to the list. The writer thread is the only thread that updates the hash
table (which happens when it flushes the temporary method buffer). So,
eventually, all TLS method lists will end up being empty because all methods
have been emitted to the output stream.
mono/profiler/proflog.c