@@ -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-
18411823static 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-
18711833static 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