This is an archive of the discontinued LLVM Phabricator instance.

Move dumping code out of RegisterValue class
ClosedPublic

Authored by labath on Jun 20 2018, 1:56 AM.

Details

Summary

The dump function was the only part of this class which depended on
high-level functionality. This was due to the DumpDataExtractor
function, which uses info from a running target to control dump format
(although, RegisterValue doesn't really use the high-level part of
DumpDataExtractor).

This patch follows the same approach done for the DataExtractor class,
and extracts the dumping code into a separate function/file. This file
can stay in the higher level code, while the RegisterValue class and
anything that does not depend in dumping can stay go to lower layers.

Event Timeline

labath created this revision.Jun 20 2018, 1:56 AM

Does anyone have an opinion on this?

davide added a subscriber: davide.Jul 19 2018, 8:07 AM

I guess this is fine. @jingham?

Seems good to me. Separating dump code from core logic is always helpful.

Is this a case of keeping RegisterValue from needing to link against the stream stuff so code inside a directory doesn't depend on code from other directories? Not sure why we wouldn't want to just ask the object itself to dump itself...

The Stream part isn't the problem. The problem is that the dumping code is implemented in terms of ExecutionContextScope, which then pulls in pretty much everything. If it was just the object "dumping itself" then I would be fine with it as a method, but here it's using the whole world to achieve that goal. At that point I would prefer it living in a separate place (though we can debate on whether it should be a completely separate file, or merged to a single file with the DumpDataExtractor code)

jingham accepted this revision.Jul 19 2018, 10:22 AM

I don't agree that moving dump routines away from the class that they are dumping is a good idea in general. It makes it harder for somebody new to the code to find out how to print out the objects, which is often handy in development as well as for logging and the like. OTOH, it seems like in this case the motivation (RegisterValue is useful on the server side so its reducing its dependencies is desirable) outweighs these downsides.

If this pattern becomes more common, then we have to deal with how somebody would find these dump routines. If RegisterValue gets moved out of Core, would you really look to a file in Core for the dump routine, especially as many other classes have an obvious Dump method?

But this change is well motivated, so as a one-off this is okay.

This revision is now accepted and ready to land.Jul 19 2018, 10:22 AM

I am fine if this helps with not pulling in the world. Seems like it should move out of Core then no? Seems weird to make the change yet keep it in the same directory.

If this pattern becomes more common, then we have to deal with how somebody would find these dump routines. If RegisterValue gets moved out of Core, would you really look to a file in Core for the dump routine, especially as many other classes have an obvious Dump method?

Do you think it would help if I merged this new file with the existing DumpDataExtractor.cpp into something like Core/Dumpers.h (I've considered something like that initially, but then chose not to in order to reduce rename churn). If there is a single file containing the dumping functions then it should just be a matter of knowing you need to look into that file. (OTOH, this way the files at least have the class name in them, so it's easier to find them by just browsing the source tree)

I am fine if this helps with not pulling in the world. Seems like it should move out of Core then no? Seems weird to make the change yet keep it in the same directory.

The plan is to move RegisterValue (along with Scalar) into Utility as a follow-up. Right now I can't think of a better place than Core for the dumping functions as (at least in their current implementations) depend on pretty much everything.

zturner added a subscriber: labath.Jul 20 2018, 7:50 AM

I had previously thought of making a top level project called Dump that
depends on everything. Also makes it very obvious where all the dumpers
are. It can have overloaded functions called lldb_private::dump(T&) for
every value of T, then no matter what type you have, all you have to do is
call dump(T). Kills all birds with one stone

Well, if it depends on everything, then it can only used from places
that also depend on everything. Right now I don't think it matters now
(though it will create a new Dump <-> "everything calling Dump"
cycle). However, I can imagine this might cause some tricky situations
later on when we try to clean up dependencies between the high level
classes.

Dump is really meant to be the private description of the object that you would use for logging and the like - Description was the public face of a class. So while the Description-like functionality could have a restrictions that constrain its use to pretty high up in the stack, you really want to be able to Dump some object you've been handed - particularly into the log stream - wherever that might help. So I don't think moving to restrict where you can use Dump is a good idea.

Dump is really meant to be the private description of the object that you would use for logging and the like - Description was the public face of a class. So while the Description-like functionality could have a restrictions that constrain its use to pretty high up in the stack, you really want to be able to Dump some object you've been handed - particularly into the log stream - wherever that might help. So I don't think moving to restrict where you can use Dump is a good idea.

I fully agree with that. It should be easy to add a simple dump function for logging purposes which omits any fancy formatting that need higher level constructs to any object. It's just that the current dump function is used for both things: logging, and displaying information to the user. I can change the name to DescribeRegisterValue or something like that if you think that makes more sense.

This revision was automatically updated to reflect the committed changes.