There is no need to iterate through all events in a profile when
loading the timeline view, as soon as we see one event we can
move on to the next process.
The architecture here is a little bit convoluted. I ended up making a
new container widget (TimelineContainer) that works similarly to
GUI::ScrollableContainerWidget but has two subwidgets (a fixed header
that only scrolls vertically, and the timeline view that scrolls on
both axes.)
It would be nice to generalize this mechanism eventually and move it
back into LibGUI, but for now let's go with a special widget for
Profiler so we can continue iterating on the GUI. :^)
Instead of smashing together all the samples into a single timeline,
make one per process and put them all in a ScrollableContainerWidget.
This makes it much easier to see which processes were active and when.
No timeline is displayed for processes with zero samples in the profile.
This turns the perfcore format into more a log than it was before,
which lets us properly log process, thread and region
creation/destruction. This also makes it unnecessary to dump the
process' regions every time it is scheduled like we did before.
Incidentally this also fixes 'profile -c' because we previously ended
up incorrectly dumping the parent's region map into the profile data.
Log-based mmap support enables profiling shared libraries which
are loaded at runtime, e.g. via dlopen().
This enables profiling both the parent and child process for
programs which use execve(). Previously we'd discard the profiling
data for the old process.
The Profiler tool has been updated to not treat thread IDs as
process IDs anymore. This enables support for processes with more
than one thread. Also, there's a new widget to filter which
process should be displayed.
SPDX License Identifiers are a more compact / standardized
way of representing file license information.
See: https://spdx.dev/resources/use/#identifiers
This was done with the `ambr` search and replace tool.
ambr --no-parent-ignore --key-from-file --rep-from-file key.txt rep.txt *
This warning informs of float-to-double conversions. The best solution
seems to be to do math *either* in 32-bit *or* in 64-bit, and only to
cross over when absolutely necessary.
I hereby declare these to be full nouns that we don't split,
neither by space, nor by underscore:
- Breadcrumbbar
- Coolbar
- Menubar
- Progressbar
- Scrollbar
- Statusbar
- Taskbar
- Toolbar
This patch makes everything consistent by replacing every other variant
of these with the proper one. :^)
The previous names (RGBA32 and RGB32) were misleading since that's not
the actual byte order in memory. The new names reflect exactly how the
color values get laid out in bitmap data.
Add Bitmap::view() and forward most of the calls to BitmapView since
the code was identical.
Bitmap is now primarily concerned with its dynamically allocated
backing store and BitmapView deals with the rest.
This is a little bit messy, but basically if an ELF object is non-PIE,
we have to account for the executable mapping being at a hard-coded
offset and subtract that when doing symbolication.
There's probably a nicer way to solve this, I just hacked this together
so we can see "cc1plus" and friends in profiles. :^)
In multi-process profiles, the same ELF objects tend to occur many
times (everyone has libc.so for example) so we will quickly run out
of VM if we map each object once per process that uses it.
Fix this by adding a "mapped object cache" that maps the path of
an ELF object to a cached memory mapping and wrapping ELF::Image.
The perfcore file format was previously limited to a single process
since the pid/executable/regions data was top-level in the JSON.
This patch moves the process-specific data into a top-level array
named "processes" and we now add entries for each process that has
been sampled during the profile run.
This makes it possible to see samples from multiple threads when
viewing a perfcore file with Profiler. This is extremely cool! :^)
You can now view the individual samples in a profile one by one with
the new "Samples" view. The "old" main view moves into a "Call Tree"
tab (but it remains the default view.)
When you select a sample in the samples view, we show you the full
symbolicated backtrace in a separate view on the right hand side. :^)
This way you don't have to look at all the library names if you don't
want to. Since we're pretty good about namespacing our things, the
library names are slightly redundant information.
If you drag-select a slice of the profile off of the side of the
Profiler window, the profiler will try to render a negative start time,
which will overflow. This commit fixes that bug by clamping timestamps
to the start/end of the profile before rendering.
(...and ASSERT_NOT_REACHED => VERIFY_NOT_REACHED)
Since all of these checks are done in release builds as well,
let's rename them to VERIFY to prevent confusion, as everyone is
used to assertions being compiled out in release.
We can introduce a new ASSERT macro that is specifically for debug
checks, but I'm doing this wholesale conversion first since we've
accumulated thousands of these already, and it's not immediately
obvious which ones are suitable for ASSERT.
Currently, there is no way to know when in a profile's duration a
sample was taken. This commit adds a basic timestamp to the timeline
widget, and a black bar to show where the cursor is hovering over.