- Parsing invalid JSON no longer asserts
Instead of asserting when coming across malformed JSON,
JsonParser::parse now returns an Optional<JsonValue>.
- Disallow trailing commas in JSON objects and arrays
- No longer parse 'undefined', as that is a purely JS thing
- No longer allow non-whitespace after anything consumed by the initial
parse() call. Examples of things that were valid and no longer are:
- undefineddfz
- {"foo": 1}abcd
- [1,2,3]4
- JsonObject.for_each_member now iterates in original insertion order
We were skipping the innermost frame as a workaround for the kernel
putting garbage data there. Now that the kernel puts the instruction
poiner there, we can load the frame normally! :^)
When you select a function in the profile tree, we will now display
a per-instruction breakdown of aggregated samples in that function.
This allows us to look much closer at what our code is doing! :^)
We were going from "new JSON format" => "old JSON format" => Event.
This made loading longer profiles unnecessarily slow. It's still pretty
slow, and we should... profile it! :^)
This makes unknown addresses accumulate their children together in the
treeview, which turns out to be a bit more useful than having hundreds
of unique garbage addresses each with their own subtree.
ProfileViewer will now attempt to open /boot/kernel and use that to
symbolicate kernel addresses (anything above the 3GB mark.)
In other words, if you run ProfileViewer as root, on a profile that
was generated by root, you can now see kernel functions properly
as well. This is not available to non-privileged users.
For memory profiles, we now keep track of which allocations are still
live at the end of the selected timeline range and only show those.
This is really cool, I have to admit. :^)
"perfcore" is the file that the kernel generates after a process that
was recording performance events has exited.
This patch teaches ProfileViewer how to load (and symbolicate!) those
files so that we can look at them. This will need a bunch more work
to make it truly useful.
I've been wanting to do this for a long time. It's time we start being
consistent about how this stuff works.
The new convention is:
- "LibFoo" is a userspace library that provides the "Foo" namespace.
That's it :^) This was pretty tedious to convert and I didn't even
start on LibGUI yet. But it's coming up next.
Technically the bottom 2MB is still identity-mapped for the kernel and
not made available to userspace at all, but for simplicity's sake we
can just ignore that and make "address < 0xc0000000" the canonical
check for user/kernel.
As suggested by Joshua, this commit adds the 2-clause BSD license as a
comment block to the top of every source file.
For the first pass, I've just added myself for simplicity. I encourage
everyone to add themselves as copyright holders of any file they've
added or modified in some significant way. If I've added myself in
error somewhere, feel free to replace it with the appropriate copyright
holder instead.
Going forward, all new source files should include a license header.
Inverting the tree turns all of the innermost stack frames into roots,
allowing them to accumulate their total sample counts with other
instances of the same frame being innermost. This is an essential
feature of any cool profiler, and now we have it. :^)
Instead of fetching these from JSON in every paint event, we now have a
separate "SampleData" vector that can be iterated.
This optimization was made possible by profiling ProfileViewer and then
analyzing the profile with ProfileViewer! :^)
You can now select the time range you want on the profile timeline.
The tree view will update automatically as you alter the range.
Unfortunately this causes the treeview to collapse all of its nodes.
It would be nice to solve this somehow in the future so that nodes
can stay open.
We begin with a simple treeview that shows a recorded profile.
To record and view a profile of a process with <PID>, simply do this:
$ profile <PID> on
... wait while PID does something interesting ...
$ profile <PID> off
$ cat /proc/profile > my-profile.prof
$ ProfileViewer my-profile.prof