Redo the way traces are managed.

The main goals of the changes are first to simplify reading/writing
data in trace.cc, and second to make trace state more explicit.  To
that end, trace.cc is now written in the C++ idiom and traces are
discrete objects (as opposed to a diffuse collection of global state).
Task is now responsible for generating most of the data that's saved
to trace; trace.cc only manages saving/restoring that data on disk.
It's still easy to get ahold of trace objects, because each Task now
owns a shared pointer to the trace it's using.

This looks like a big scary patch, but actually the changes outside of trace.{cc,h} were quite straightforward.  It would have been possible with some effort to break this into smaller chunks, but I didn't think the effort would have been worth it.

Apologies if this significantly bitrots anyone.

Resolves #802.