diff options
Diffstat (limited to 'compiler-rt/lib/profile/InstrProfilingBuffer.c')
-rw-r--r-- | compiler-rt/lib/profile/InstrProfilingBuffer.c | 70 |
1 files changed, 66 insertions, 4 deletions
diff --git a/compiler-rt/lib/profile/InstrProfilingBuffer.c b/compiler-rt/lib/profile/InstrProfilingBuffer.c index 5bdeb8e32807..174280fd4b52 100644 --- a/compiler-rt/lib/profile/InstrProfilingBuffer.c +++ b/compiler-rt/lib/profile/InstrProfilingBuffer.c @@ -8,6 +8,23 @@ #include "InstrProfiling.h" #include "InstrProfilingInternal.h" +#include "InstrProfilingPort.h" + +/* When continuous mode is enabled (%c), this parameter is set to 1. + * + * This parameter is defined here in InstrProfilingBuffer.o, instead of in + * InstrProfilingFile.o, to sequester all libc-dependent code in + * InstrProfilingFile.o. The test `instrprof-without-libc` will break if this + * layering is violated. */ +static int ContinuouslySyncProfile = 0; + +COMPILER_RT_VISIBILITY int __llvm_profile_is_continuous_mode_enabled(void) { + return ContinuouslySyncProfile; +} + +COMPILER_RT_VISIBILITY void __llvm_profile_enable_continuous_mode(void) { + ContinuouslySyncProfile = 1; +} COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_size_for_buffer(void) { @@ -30,6 +47,41 @@ uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, sizeof(__llvm_profile_data); } +/// Calculate the number of padding bytes needed to add to \p Offset in order +/// for (\p Offset + Padding) to be page-aligned. +static uint64_t calculateBytesNeededToPageAlign(uint64_t Offset, + unsigned PageSize) { + uint64_t OffsetModPage = Offset % PageSize; + if (OffsetModPage > 0) + return PageSize - OffsetModPage; + return 0; +} + +COMPILER_RT_VISIBILITY +void __llvm_profile_get_padding_sizes_for_counters( + uint64_t DataSize, uint64_t CountersSize, uint64_t NamesSize, + uint64_t *PaddingBytesBeforeCounters, uint64_t *PaddingBytesAfterCounters, + uint64_t *PaddingBytesAfterNames) { + if (!__llvm_profile_is_continuous_mode_enabled()) { + *PaddingBytesBeforeCounters = 0; + *PaddingBytesAfterCounters = 0; + *PaddingBytesAfterNames = __llvm_profile_get_num_padding_bytes(NamesSize); + return; + } + + // In continuous mode, the file offsets for headers and for the start of + // counter sections need to be page-aligned. + unsigned PageSize = getpagesize(); + uint64_t DataSizeInBytes = DataSize * sizeof(__llvm_profile_data); + uint64_t CountersSizeInBytes = CountersSize * sizeof(uint64_t); + *PaddingBytesBeforeCounters = calculateBytesNeededToPageAlign( + sizeof(__llvm_profile_header) + DataSizeInBytes, PageSize); + *PaddingBytesAfterCounters = + calculateBytesNeededToPageAlign(CountersSizeInBytes, PageSize); + *PaddingBytesAfterNames = + calculateBytesNeededToPageAlign(NamesSize, PageSize); +} + COMPILER_RT_VISIBILITY uint64_t __llvm_profile_get_size_for_buffer_internal( const __llvm_profile_data *DataBegin, const __llvm_profile_data *DataEnd, @@ -37,11 +89,21 @@ uint64_t __llvm_profile_get_size_for_buffer_internal( const char *NamesBegin, const char *NamesEnd) { /* Match logic in __llvm_profile_write_buffer(). */ const uint64_t NamesSize = (NamesEnd - NamesBegin) * sizeof(char); - const uint8_t Padding = __llvm_profile_get_num_padding_bytes(NamesSize); + uint64_t DataSize = __llvm_profile_get_data_size(DataBegin, DataEnd); + uint64_t CountersSize = CountersEnd - CountersBegin; + + /* Determine how much padding is needed before/after the counters and after + * the names. */ + uint64_t PaddingBytesBeforeCounters, PaddingBytesAfterCounters, + PaddingBytesAfterNames; + __llvm_profile_get_padding_sizes_for_counters( + DataSize, CountersSize, NamesSize, &PaddingBytesBeforeCounters, + &PaddingBytesAfterCounters, &PaddingBytesAfterNames); + return sizeof(__llvm_profile_header) + - (__llvm_profile_get_data_size(DataBegin, DataEnd) * - sizeof(__llvm_profile_data)) + - (CountersEnd - CountersBegin) * sizeof(uint64_t) + NamesSize + Padding; + (DataSize * sizeof(__llvm_profile_data)) + PaddingBytesBeforeCounters + + (CountersSize * sizeof(uint64_t)) + PaddingBytesAfterCounters + + NamesSize + PaddingBytesAfterNames; } COMPILER_RT_VISIBILITY |