-
Notifications
You must be signed in to change notification settings - Fork 40
Emit memory reports to debug link time memory usage #620
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
This prints memory allocated by linker core data structures with a count of how many and total bytes used. This will be followed up by improvements to report virtual memory / resident memory size. Resolves #606 Signed-off-by: Shankar Easwaran <[email protected]>
761a3d7 to
b751bc6
Compare
| */ | ||
| class GeneralOptions { | ||
| public: | ||
| static std::string getTypeName() { return "GeneralOptions"; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we please return std::string_view / llvm::StringRef / const char * instead of std::string as these are more memory efficient?
| // --emit-memory-report <file> | ||
| std::string getMemoryReportFile() const { return MemoryReportFile; } | ||
|
|
||
| void setMemoryReportFile(std::string F) { MemoryReportFile = F; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should try to use llvm::StringRef / std::string_view wherever we can as they avoid copying strings. What do you think about it?
| void setMemoryReportFile(std::string F) { MemoryReportFile = F; } | |
| void setMemoryReportFile(llvm::StringRef F) { MemoryReportFile = F; } |
| void setPrintMemoryReport() { PrintMemoryReport = true; } | ||
|
|
||
| // --emit-memory-report <file> | ||
| std::string getMemoryReportFile() const { return MemoryReportFile; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| std::string getMemoryReportFile() const { return MemoryReportFile; } | |
| llvm::StringRef getMemoryReportFile() const { return MemoryReportFile; } |
| std::string TarFile; // --reproduce output tarfile name | ||
| std::string TimingStatsFile; | ||
| std::string TimingStatsFile; // --emit-timing-stats | ||
| std::string MemoryReportFile; // --emit-memory-report |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we use one option std::optional<MemoryReportFile> instead of using two options PrintMemoryReport and MemoryReportFile?
|
|
||
| // Use this arena if your object has a destructor. | ||
| // Your destructor will be invoked from freeArena(). | ||
| template <typename T, typename... U> T *make(U &&...Args) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What do you think about adding the below macro for make (and slightly modifying eld::make definition) and directly using the type name supplied by the macro user to initialize the TypeName property of SpecificAlloc? I believe this will make the design significantly more maintainable and scalable.
#define MAKE(Type, ...) \
eld::make<Type>(#Type, __VA_ARGS__);
template<typename T, typename... U> T *make(llvm::StringRef TypeName, U &&... Args) {
return ArenaForType<T>::create(TypeName, std::forward<T>(Args)...);
}Now ArenaForType can directly use TypeName to initialize SpecificAlloc.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i like this way better, though this will need every make(X) to be changed to make(T, X)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even currently, all make calls are of the form: make<T>(X). We still have T in the make calls :).
| bool GnuLdDriver::emitMemoryReport() const { | ||
| if (!Config.options().showMemoryReport()) | ||
| return true; | ||
| std::string File = Config.options().getMemoryReportFile(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| std::string File = Config.options().getMemoryReportFile(); | |
| llvm::StringRef File = Config.options().getMemoryReportFile(); |
| */ | ||
| class BranchIsland { | ||
| public: | ||
| static std::string getTypeName() { return "BranchIsland"; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we use macros to get these? Adding this to every single type feels needlessly complex and hard to scale.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. I think that is much better. Let me explore
| return "parsing_failed"; | ||
| start += strlen("parseTypeNameFromSignature<"); | ||
|
|
||
| // MSVC might add "class ", "struct ", etc. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do we need this extra complexity for mscv?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes.
| void setTimingStatsFile(std::string StatsFile) { | ||
| TimingStatsFile = StatsFile; | ||
| } | ||
| //--------------------Memory Report-------------------------------- |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
is this feature useful to anyone other than an eld developer?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Only eld developer.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I can make this option hidden if that is what you were hinting at.
This prints memory allocated by linker core data structures with a count of how many and total bytes used.
This will be followed up by improvements to report virtual memory / resident memory size.
Resolves #606