@@ -1803,28 +1803,12 @@ static std::pair<bool, bool> uses_specsig(jl_method_instance_t *lam, jl_value_t
1803
1803
1804
1804
// Logging for code coverage and memory allocation
1805
1805
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) ;
1809
1809
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 )
1811
1811
{
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);
1828
1812
Value *pv = ConstantExpr::getIntToPtr(
1829
1813
ConstantInt::get(T_size, (uintptr_t)ptr),
1830
1814
T_pint64);
@@ -1836,38 +1820,16 @@ static void visitLine(jl_codectx_t &ctx, std::vector<logdata_block*> &vec, int l
1836
1820
1837
1821
// Code coverage
1838
1822
1839
- static logdata_t coverageData;
1840
-
1841
1823
static void coverageVisitLine(jl_codectx_t &ctx, StringRef filename, int line)
1842
1824
{
1843
1825
assert(!imaging_mode);
1844
1826
if (filename == "" || filename == "none" || filename == "no file" || filename == "<missing>" || line < 0)
1845
1827
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");
1865
1829
}
1866
1830
1867
1831
// Memory allocation log (malloc_log)
1868
1832
1869
- static logdata_t mallocData;
1870
-
1871
1833
static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Value *sync)
1872
1834
{
1873
1835
assert(!imaging_mode);
@@ -1876,143 +1838,7 @@ static void mallocVisitLine(jl_codectx_t &ctx, StringRef filename, int line, Val
1876
1838
Value *addend = sync
1877
1839
? ctx.builder.CreateCall(prepare_call(sync_gc_total_bytes_func), {sync})
1878
1840
: 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");
2016
1842
}
2017
1843
2018
1844
// --- constant determination ---
@@ -7073,7 +6899,7 @@ static std::pair<std::unique_ptr<Module>, jl_llvm_functions_t>
7073
6899
// record all lines that could be covered
7074
6900
for (const auto &info : linetable)
7075
6901
if (do_coverage(info.is_user_code))
7076
- coverageAllocLine (info.file, info.line);
6902
+ jl_coverage_alloc_line (info.file, info.line);
7077
6903
}
7078
6904
7079
6905
come_from_bb[0] = ctx.builder.GetInsertBlock();
0 commit comments