Skip to content

Commit 6a9737d

Browse files
authored
fix JuliaLang#42659, move jl_coverage_visit_line to runtime library (JuliaLang#42810)
1 parent c762f10 commit 6a9737d

File tree

6 files changed

+225
-188
lines changed

6 files changed

+225
-188
lines changed

src/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ RUNTIME_SRCS := \
4747
simplevector runtime_intrinsics precompile \
4848
threading partr stackwalk gc gc-debug gc-pages gc-stacks method \
4949
jlapi signal-handling safepoint timing subtype \
50-
crc32c APInt-C processor ircode opaque_closure codegen-stubs
50+
crc32c APInt-C processor ircode opaque_closure codegen-stubs coverage
5151
SRCS := jloptions runtime_ccall rtutils
5252
ifeq ($(OS),WINNT)
5353
SRCS += win32_ucontext

src/codegen-stubs.c

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,7 @@ JL_DLLEXPORT void jl_dump_native_fallback(void *native_code,
1414
const char *bc_fname, const char *unopt_bc_fname, const char *obj_fname, const char *asm_fname,
1515
const char *sysimg_data, size_t sysimg_len) UNAVAILABLE
1616
JL_DLLEXPORT int32_t jl_get_llvm_gv_fallback(void *native_code, jl_value_t *p) UNAVAILABLE
17-
JL_DLLEXPORT void jl_write_malloc_log_fallback(void) UNAVAILABLE
18-
JL_DLLEXPORT void jl_write_coverage_data_fallback(const char *output) UNAVAILABLE
1917

20-
JL_DLLEXPORT void jl_clear_malloc_data_fallback(void) UNAVAILABLE
2118
JL_DLLEXPORT int jl_extern_c_fallback(jl_function_t *f, jl_value_t *rt, jl_value_t *argt, char *name) UNAVAILABLE
2219
JL_DLLEXPORT jl_value_t *jl_dump_method_asm_fallback(jl_method_instance_t *linfo, size_t world,
2320
char raw_mc, char getwrapper, const char* asm_variant, const char *debuginfo, char binary) UNAVAILABLE

src/codegen.cpp

Lines changed: 7 additions & 181 deletions
Original file line numberDiff line numberDiff line change
@@ -1803,28 +1803,12 @@ static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t
18031803

18041804
// Logging for code coverage and memory allocation
18051805

1806-
const int logdata_blocksize = 32; // target getting nearby lines in the same general cache area and reducing calls to malloc by chunking
1807-
typedef uint64_t logdata_block[logdata_blocksize];
1808-
typedef StringMap< std::vector<logdata_block*> > logdata_t;
1806+
JL_DLLEXPORT void jl_coverage_alloc_line(StringRef filename, int line);
1807+
JL_DLLEXPORT uint64_t *jl_coverage_data_pointer(StringRef filename, int line);
1808+
JL_DLLEXPORT uint64_t *jl_malloc_data_pointer(StringRef filename, int line);
18091809

1810-
static uint64_t *allocLine(std::vector<logdata_block*> &vec, int line)
1810+
static void visitLine(jl_codectx_t &ctx, uint64_t *ptr, Value *addend, const char *name)
18111811
{
1812-
unsigned block = line / logdata_blocksize;
1813-
line = line % logdata_blocksize;
1814-
if (vec.size() <= block)
1815-
vec.resize(block + 1);
1816-
if (vec[block] == NULL) {
1817-
vec[block] = (logdata_block*)calloc(1, sizeof(logdata_block));
1818-
}
1819-
logdata_block &data = *vec[block];
1820-
if (data[line] == 0)
1821-
data[line] = 1;
1822-
return &data[line];
1823-
}
1824-
1825-
static void visitLine(jl_codectx_t &ctx, std::vector<logdata_block*> &vec, int line, Value *addend, const char* name)
1826-
{
1827-
uint64_t *ptr = allocLine(vec, line);
18281812
Value *pv = ConstantExpr::getIntToPtr(
18291813
ConstantInt::get(T_size, (uintptr_t)ptr),
18301814
T_pint64);
@@ -1836,38 +1820,16 @@ static void visitLine(jl_codectx_t &ctx, std::vector<logdata_block*> &vec, int l
18361820

18371821
// Code coverage
18381822

1839-
static logdata_t coverageData;
1840-
18411823
static void coverageVisitLine(jl_codectx_t &ctx, StringRef filename, int line)
18421824
{
18431825
assert(!imaging_mode);
18441826
if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
18451827
return;
1846-
visitLine(ctx, coverageData[filename], line, ConstantInt::get(T_int64, 1), "lcnt");
1847-
}
1848-
1849-
static void coverageAllocLine(StringRef filename, int line)
1850-
{
1851-
assert(!imaging_mode);
1852-
if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
1853-
return;
1854-
allocLine(coverageData[filename], line);
1855-
}
1856-
1857-
extern "C" JL_DLLEXPORT void jl_coverage_visit_line(const char* filename_, size_t len_filename, int line)
1858-
{
1859-
StringRef filename = StringRef(filename_, len_filename);
1860-
if (imaging_mode || filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
1861-
return;
1862-
std::vector<logdata_block*> &vec = coverageData[filename];
1863-
uint64_t *ptr = allocLine(vec, line);
1864-
(*ptr)++;
1828+
visitLine(ctx, jl_coverage_data_pointer(filename, line), ConstantInt::get(T_int64, 1), "lcnt");
18651829
}
18661830

18671831
// Memory allocation log (malloc_log)
18681832

1869-
static logdata_t mallocData;
1870-
18711833
static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Value *sync)
18721834
{
18731835
assert(!imaging_mode);
@@ -1876,143 +1838,7 @@ static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Val
18761838
Value *addend = sync
18771839
? ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync})
18781840
: ctx.builder.CreateCall(prepare_call(diff_gc_total_bytes_func), {});
1879-
visitLine(ctx, mallocData[filename], line, addend, "bytecnt");
1880-
}
1881-
1882-
// Resets the malloc counts.
1883-
extern "C" JL_DLLEXPORT void jl_clear_malloc_data_impl(void)
1884-
{
1885-
logdata_t::iterator it = mallocData.begin();
1886-
for (; it != mallocData.end(); it++) {
1887-
std::vector<logdata_block*> &bytes = (*it).second;
1888-
std::vector<logdata_block*>::iterator itb;
1889-
for (itb = bytes.begin(); itb != bytes.end(); itb++) {
1890-
if (*itb) {
1891-
logdata_block &data = **itb;
1892-
for (int i = 0; i < logdata_blocksize; i++) {
1893-
if (data[i] > 0)
1894-
data[i] = 1;
1895-
}
1896-
}
1897-
}
1898-
}
1899-
jl_gc_sync_total_bytes(0);
1900-
}
1901-
1902-
static void write_log_data(logdata_t &logData, const char *extension)
1903-
{
1904-
std::string base = std::string(jl_options.julia_bindir);
1905-
base = base + "/../share/julia/base/";
1906-
logdata_t::iterator it = logData.begin();
1907-
for (; it != logData.end(); it++) {
1908-
std::string filename(it->first());
1909-
std::vector<logdata_block*> &values = it->second;
1910-
if (!values.empty()) {
1911-
if (!jl_isabspath(filename.c_str()))
1912-
filename = base + filename;
1913-
std::ifstream inf(filename.c_str());
1914-
if (!inf.is_open())
1915-
continue;
1916-
std::string outfile = filename + extension;
1917-
std::ofstream outf(outfile.c_str(), std::ofstream::trunc | std::ofstream::out | std::ofstream::binary);
1918-
if (outf.is_open()) {
1919-
inf.exceptions(std::ifstream::badbit);
1920-
outf.exceptions(std::ifstream::failbit | std::ifstream::badbit);
1921-
char line[1024];
1922-
int l = 1;
1923-
unsigned block = 0;
1924-
while (!inf.eof()) {
1925-
inf.getline(line, sizeof(line));
1926-
if (inf.fail()) {
1927-
if (inf.eof())
1928-
break; // no content on trailing line
1929-
// Read through lines longer than sizeof(line)
1930-
inf.clear();
1931-
inf.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
1932-
}
1933-
logdata_block *data = NULL;
1934-
if (block < values.size()) {
1935-
data = values[block];
1936-
}
1937-
uint64_t value = data ? (*data)[l] : 0;
1938-
if (++l >= logdata_blocksize) {
1939-
l = 0;
1940-
block++;
1941-
}
1942-
outf.width(9);
1943-
if (value == 0)
1944-
outf << '-';
1945-
else
1946-
outf << (value - 1);
1947-
outf.width(0);
1948-
outf << " " << line << '\n';
1949-
}
1950-
outf.close();
1951-
}
1952-
inf.close();
1953-
}
1954-
}
1955-
}
1956-
1957-
static void write_lcov_data(logdata_t &logData, const std::string &outfile)
1958-
{
1959-
std::ofstream outf(outfile.c_str(), std::ofstream::ate | std::ofstream::out | std::ofstream::binary);
1960-
//std::string base = std::string(jl_options.julia_bindir);
1961-
//base = base + "/../share/julia/base/";
1962-
logdata_t::iterator it = logData.begin();
1963-
for (; it != logData.end(); it++) {
1964-
StringRef filename = it->first();
1965-
const std::vector<logdata_block*> &values = it->second;
1966-
if (!values.empty()) {
1967-
outf << "SF:" << filename.str() << '\n';
1968-
size_t n_covered = 0;
1969-
size_t n_instrumented = 0;
1970-
size_t lno = 0;
1971-
for (auto &itv : values) {
1972-
if (itv) {
1973-
logdata_block &data = *itv;
1974-
for (int i = 0; i < logdata_blocksize; i++) {
1975-
auto cov = data[i];
1976-
if (cov > 0) {
1977-
n_instrumented++;
1978-
if (cov > 1)
1979-
n_covered++;
1980-
outf << "DA:" << lno << ',' << (cov - 1) << '\n';
1981-
}
1982-
lno++;
1983-
}
1984-
}
1985-
else {
1986-
lno += logdata_blocksize;
1987-
}
1988-
}
1989-
outf << "LH:" << n_covered << '\n';
1990-
outf << "LF:" << n_instrumented << '\n';
1991-
outf << "end_of_record\n";
1992-
}
1993-
}
1994-
outf.close();
1995-
}
1996-
1997-
extern "C" JL_DLLEXPORT void jl_write_coverage_data_impl(const char *output)
1998-
{
1999-
if (output) {
2000-
StringRef output_pattern(output);
2001-
if (output_pattern.endswith(".info"))
2002-
write_lcov_data(coverageData, jl_format_filename(output_pattern.str().c_str()));
2003-
}
2004-
else {
2005-
std::string stm;
2006-
raw_string_ostream(stm) << "." << jl_getpid() << ".cov";
2007-
write_log_data(coverageData, stm.c_str());
2008-
}
2009-
}
2010-
2011-
extern "C" JL_DLLEXPORT void jl_write_malloc_log_impl(void)
2012-
{
2013-
std::string stm;
2014-
raw_string_ostream(stm) << "." << jl_getpid() << ".mem";
2015-
write_log_data(mallocData, stm.c_str());
1841+
visitLine(ctx, jl_malloc_data_pointer(filename, line), addend, "bytecnt");
20161842
}
20171843

20181844
// --- constant determination ---
@@ -7073,7 +6899,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
70736899
// record all lines that could be covered
70746900
for (const auto &info : linetable)
70756901
if (do_coverage(info.is_user_code))
7076-
coverageAllocLine(info.file, info.line);
6902+
jl_coverage_alloc_line(info.file, info.line);
70776903
}
70786904

70796905
come_from_bb[0] = ctx.builder.GetInsertBlock();

0 commit comments

Comments
 (0)