In environments with tight memory constraints, users may not be able to actually allocate a buffer large enough to fit all of their program's profiling data.
In this case, a workflow like this would be helpful:
while (!__llvm_profile_incremental_writer_done()) { char Buffer[BUFFER_SIZE]; if (__llvm_profile_write_buffer_incremental(Buffer, BUFFER_SIZE) == -1) return -1; if (putBufferSomewhere(Buffer, BUFFER_SIZE)) return -1; }
That is, make a smaller buffer, fill it with BUFFER_SIZE bytes of data, transfer that somewhere else, and repeat the process until all of the profiling data has been transferred out.
This patch adds the state and APIs necessary to make the above workflow possible.
The added APIs are as follows:
- int __llvm_profile_init_incremental_writer_state(void) - Initializes internal structures to remember where we are in the process of writing profiling data
- __llvm_profile_write_buffer_incremental(char *Buffer, uint64_t WriteSizeInBytes) - Writes a certain number of bytes into a buffer
- int __llvm_profile_incremental_writer_done(void) - Returns whether or not all profiling bytes have been written
The added state is a struct (IncrementalProfileWriterState) that keeps track of
- How many sources we need to write data from
- What those sources are
- Which source we're writing from, and where in it we should write from
The struct reuses the existing ProfDataIOVec structure used throughout the rest of libprofile.
Currently, binary ID writing is not supported, since it seems very platform-specific. This will emit a warning on platforms that enable binary ID writing.
This patch also adds a couple refactors/error message improvements:
- Factor out some of the header construction code in lprofWriteDataImpl
- Add a PROF_ERR_INTERNAL to communicate when an error is likely not a user error, but rather a bug of some sort
This struct is fairly large and would be always allocated, even if we aren't using the incremental mode unless it can be GC'ed by the linker (which requires compiling with GC enabled which isn't enabled by default on all platforms).
Could we move all the symbols related to the incremental mode into a separate TU so if the incremental mode isn't being used, those symbols won't be pulled into the link in in the first place?