llvm-project/compiler-rt/lib/profile/InstrProfilingBuffer.c
Xinliang David Li 4da5de9c34 Use struct type instead of raw array for raw profile header (NFC)
This patch introduces a well defined header struct
to represent raw profile header instead of using raw array.
Previously the raw array is used in two different files and
is very error prone when header structure is re-organized.
This is a small cleanup with NFC.

llvm-svn: 250561
2015-10-16 22:21:56 +00:00

105 lines
4.1 KiB
C

/*===- InstrProfilingBuffer.c - Write instrumentation to a memory buffer --===*\
|*
|* The LLVM Compiler Infrastructure
|*
|* This file is distributed under the University of Illinois Open Source
|* License. See LICENSE.TXT for details.
|*
\*===----------------------------------------------------------------------===*/
#include "InstrProfiling.h"
#include "InstrProfilingInternal.h"
#include <string.h>
__attribute__((visibility("hidden")))
uint64_t __llvm_profile_get_size_for_buffer(void) {
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const uint64_t *CountersBegin = __llvm_profile_begin_counters();
const uint64_t *CountersEnd = __llvm_profile_end_counters();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
return __llvm_profile_get_size_for_buffer_internal(
DataBegin, DataEnd, CountersBegin, CountersEnd, NamesBegin, NamesEnd);
}
#define PROFILE_RANGE_SIZE(Range) (Range##End - Range##Begin)
__attribute__((visibility("hidden")))
uint64_t __llvm_profile_get_size_for_buffer_internal(
const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,
const uint64_t *CountersEnd, const char *NamesBegin,
const char *NamesEnd) {
/* Match logic in __llvm_profile_write_buffer(). */
const uint64_t NamesSize = PROFILE_RANGE_SIZE(Names) * sizeof(char);
const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
return sizeof(__llvm_profile_header) +
PROFILE_RANGE_SIZE(Data) * sizeof(__llvm_profile_data) +
PROFILE_RANGE_SIZE(Counters) * sizeof(uint64_t) +
NamesSize + Padding;
}
__attribute__((visibility("hidden")))
int __llvm_profile_write_buffer(char *Buffer) {
/* Match logic in __llvm_profile_get_size_for_buffer().
* Match logic in __llvm_profile_write_file().
*/
const __llvm_profile_data *DataBegin = __llvm_profile_begin_data();
const __llvm_profile_data *DataEnd = __llvm_profile_end_data();
const uint64_t *CountersBegin = __llvm_profile_begin_counters();
const uint64_t *CountersEnd = __llvm_profile_end_counters();
const char *NamesBegin = __llvm_profile_begin_names();
const char *NamesEnd = __llvm_profile_end_names();
return __llvm_profile_write_buffer_internal(Buffer, DataBegin, DataEnd,
CountersBegin, CountersEnd,
NamesBegin, NamesEnd);
}
__attribute__((visibility("hidden")))
int __llvm_profile_write_buffer_internal(
char *Buffer, const __llvm_profile_data *DataBegin,
const __llvm_profile_data *DataEnd, const uint64_t *CountersBegin,
const uint64_t *CountersEnd, const char *NamesBegin, const char *NamesEnd) {
/* Match logic in __llvm_profile_get_size_for_buffer().
* Match logic in __llvm_profile_write_file().
*/
/* Calculate size of sections. */
const uint64_t DataSize = DataEnd - DataBegin;
const uint64_t CountersSize = CountersEnd - CountersBegin;
const uint64_t NamesSize = NamesEnd - NamesBegin;
const uint64_t Padding = sizeof(uint64_t) - NamesSize % sizeof(uint64_t);
/* Enough zeroes for padding. */
const char Zeroes[sizeof(uint64_t)] = {0};
/* Create the header. */
__llvm_profile_header Header;
Header.Magic = __llvm_profile_get_magic();
Header.Version = __llvm_profile_get_version();
Header.DataSize = DataSize;
Header.CountersSize = CountersSize;
Header.NamesSize = NamesSize;
Header.CountersDelta = (uintptr_t)CountersBegin;
Header.NamesDelta = (uintptr_t)NamesBegin;
/* Write the data. */
#define UPDATE_memcpy(Data, Size) \
do { \
memcpy(Buffer, Data, Size); \
Buffer += Size; \
} while (0)
UPDATE_memcpy(&Header, sizeof(__llvm_profile_header));
UPDATE_memcpy(DataBegin, DataSize * sizeof(__llvm_profile_data));
UPDATE_memcpy(CountersBegin, CountersSize * sizeof(uint64_t));
UPDATE_memcpy(NamesBegin, NamesSize * sizeof(char));
UPDATE_memcpy(Zeroes, Padding * sizeof(char));
#undef UPDATE_memcpy
return 0;
}