This is an archive of the discontinued LLVM Phabricator instance.

Separate file parsing from File's constructors.
ClosedPublic

Authored by ruiu on Dec 11 2014, 6:28 PM.

Details

Summary

This is a second patch for InputGraph cleanup.

Sorry about the size of the patch, but what I did in this
patch is basically moving code from constructor to a new
method, parse(), so the amount of new code is small.
This has no change in functionality.

We've discussed the issue that we have too many classes
to represent a concept of "file". We have File subclasses
that represent files read from disk. In addition to that,
we have bunch of InputElement subclasses (that are part
of InputGraph) that represent command line arguments for
input file names. InputElement is a wrapper for File.

InputElement has parseFile method. The method instantiates
a File. The File's constructor reads a file from disk and
parses that.

Because parseFile method is called from multiple worker
threads, file parsing is processed in parallel. In other
words, one reason why we needed the wrapper classes is
because a File would start reading a file as soon as it
is instantiated.

So, the reason why we have too many classes here is at
least partly because of the design flaw of File class.
Just like threads in a good threading library, we need
to separate instantiation from "start" method, so that
we can instantiate File objects when we need them (which
should be very fast because it involves only one mmap()
and no real file IO) and use them directly instead of
the wrapper classes. Later, we call parse() on each
file in parallel to let them do actual file IO.

In this design, we can eliminate a reason to have the
wrapper classes.

In order to minimize the size of the patch, I didn't go so
far as to replace the wrapper classes with File classes.
The wrapper classes are still there.

In this patch, we call parse() immediately after
instantiating a File, so this really has no change in
functionality. Eventually the call of parse() should be
moved to Driver::link(). That'll be done in another patch.

Diff Detail

Event Timeline

ruiu updated this revision to Diff 17201.Dec 11 2014, 6:28 PM
ruiu retitled this revision from to Separate file parsing from File's constructors..
ruiu updated this object.
ruiu edited the test plan for this revision. (Show Details)
ruiu added a project: lld.
ruiu added a subscriber: Unknown Object (MLST).
Bigcheese accepted this revision.Dec 11 2014, 7:11 PM
Bigcheese edited edge metadata.

lgtm other than the error semantics.

lib/ReaderWriter/ELF/DynamicFile.h
58–61

The error semantics here are a bit weird. All calls to parse() will not error after the first, even if the first errors out.

This revision is now accepted and ready to land.Dec 11 2014, 7:11 PM
ruiu added inline comments.Dec 11 2014, 7:20 PM
lib/ReaderWriter/ELF/DynamicFile.h
58–61

Good point. I wanted to make this function idempotent, so returning a different result on second call is wrong. I'll fix this.

shankarke added inline comments.Dec 11 2014, 7:38 PM
include/lld/Core/File.h
157–158

Can you add doxygen comments here.

232

There is only one state being tracked, what about parsed but there was an error ? If there is a call that calls the parse function again, it will return success.

lib/ReaderWriter/ELF/ELFFile.h
421–422

Why std::move again ?

lib/ReaderWriter/MachO/File.h
209

should this be a unique_ptr ?

ruiu updated this revision to Diff 17207.Dec 11 2014, 7:53 PM
ruiu edited edge metadata.
ruiu added inline comments.
include/lld/Core/File.h
157–158

Done

232

That is what Michael pointed out. Made a change to save the last error code instead of a boolean value

lib/ReaderWriter/ELF/ELFFile.h
421–422

Removed.

lib/ReaderWriter/MachO/File.h
209

I was tempted to make this a std::unique_ptr but decided to not do that. This is the mechanical translation of the original code. If this has to be fixed, it should be done in a followup patch.

ruiu updated this revision to Diff 17208.Dec 11 2014, 7:57 PM
shankarke accepted this revision.Dec 11 2014, 8:05 PM
shankarke edited edge metadata.
atanasyan accepted this revision.Dec 11 2014, 8:56 PM
atanasyan edited edge metadata.

LGTM

include/lld/Core/File.h
159

Can we make this virtual method abstract?

kledzik edited edge metadata.Dec 12 2014, 12:24 PM

The method Reader::parseFile() no longer has an appropriate name (since it no longer parses). It now just constructs a File object.

include/lld/Core/File.h
157–171

It is not clear why we need "lastError". You say it is for YAML, but the YAML reader could be changed to return some File object which you can later call parse() on. With that gone, you don't need to parse() and doParse(). You can have just parse() which subclasses override to do the actual parsing.

atanasyan resigned from this revision.Feb 2 2016, 10:29 PM
atanasyan removed a reviewer: atanasyan.
Eugene.Zelenko added a subscriber: Eugene.Zelenko.

Committed in r224102.