smspillaz/gjs — pull request #1 by smspillaz (2013-12-26 18:59:24+00:00)
Title: Add Code Coverage Support for GJS

This branch adds code coverage support to Gjs.

One of the main items of work here was to provide a suitable abstraction for the debugger functionality in SpiderMonkey so that multiple clients could use it concurrently (eg, the function profiler and the code coverage tool and potentially a real debugger in the future).

This is provided through the GjsInterruptRegister interface (and its implementation GjsDebugInterruptRegister). It effectively works by providing a central place where clients can add callbacks and each of its functions returns a GjsDebugConnection. Once the client is done using the debugger in the way that they need to, they simply unref the connection and it will call back into the interrupt register and change the SpiderMonkey state appropriately if need be.

GjsProfiler and GjsCoverage effectively work by using this interface, the former placing a hook on toplevel execution and function calls and the latter putting the script under coverage into single-step mode where we can record line hit information. It then (if requested) will require this information out to a file.

Q & A:

* Q: Why not use signals?
* A: Signals don't provide us with a means to get a notification when the observer starts or stops observing a signal. We need this information in order to put SpiderMonkey in the right state when we need it (else keeping the debugging hooks on indefinitely will be needlessly expensive).

* Q: The object ownership between GjsInterruptRegister, GjsCoverage and GjsProfiler seems strange.
* A: This is an area I'd like some feedback and advice. The design would be far more optimal if GjsCoverage and GjsProfiler took ownership of GjsinterruptRegister outside the scope of the context as opposed to within it. However, it seems like the Gjs authors wanted to be able to use the profiler with any that uses Gjs as an embedded language, which means that the profiler needed to be owned (and created by) the context. This in turn means that we need to have GjsCoverage owned by the context as well. However, it is slightly awkward, since in order to construct it we need to have clients provide the requested coverage paths and coverage output file in the form of construction properties.