diff options
Diffstat (limited to 'contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c')
| -rw-r--r-- | contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c | 70 | 
1 files changed, 66 insertions, 4 deletions
diff --git a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c b/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c index 5bdeb8e32807..174280fd4b52 100644 --- a/contrib/llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c +++ b/contrib/llvm-project/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  | 
