coverage: Don't convert filenames to CString for FFI

This commit is contained in:
Zalathar 2023-07-24 17:27:29 +10:00
parent 474709a9a2
commit e184118683
4 changed files with 34 additions and 19 deletions

View File

@ -12,8 +12,7 @@ use rustc_middle::bug;
use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
use rustc_middle::mir::coverage::CodeRegion;
use rustc_middle::ty::TyCtxt;
use std::ffi::CString;
use rustc_span::Symbol;
/// Generates and exports the Coverage Map.
///
@ -89,7 +88,10 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
// Encode all filenames referenced by counters/expressions in this module
let filenames_buffer = llvm::build_byte_buffer(|filenames_buffer| {
coverageinfo::write_filenames_section_to_buffer(&mapgen.filenames, filenames_buffer);
coverageinfo::write_filenames_section_to_buffer(
mapgen.filenames.iter().map(Symbol::as_str),
filenames_buffer,
);
});
let filenames_size = filenames_buffer.len();
@ -117,7 +119,7 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
}
struct CoverageMapGenerator {
filenames: FxIndexSet<CString>,
filenames: FxIndexSet<Symbol>,
}
impl CoverageMapGenerator {
@ -128,11 +130,10 @@ impl CoverageMapGenerator {
// Since rustc generates coverage maps with relative paths, the
// compilation directory can be combined with the relative paths
// to get absolute paths, if needed.
let working_dir =
tcx.sess.opts.working_dir.remapped_path_if_available().to_string_lossy().to_string();
let c_filename =
CString::new(working_dir).expect("null error converting filename to C string");
filenames.insert(c_filename);
let working_dir = Symbol::intern(
&tcx.sess.opts.working_dir.remapped_path_if_available().to_string_lossy(),
);
filenames.insert(working_dir);
Self { filenames }
}
@ -170,10 +171,8 @@ impl CoverageMapGenerator {
current_file_id += 1;
}
current_file_name = Some(file_name);
let c_filename = CString::new(file_name.to_string())
.expect("null error converting filename to C string");
debug!(" file_id: {} = '{:?}'", current_file_id, c_filename);
let (filenames_index, _) = self.filenames.insert_full(c_filename);
debug!(" file_id: {} = '{:?}'", current_file_id, file_name);
let (filenames_index, _) = self.filenames.insert_full(file_name);
virtual_file_mapping.push(filenames_index as u32);
}
debug!("Adding counter {:?} to map for {:?}", counter, region);

View File

@ -339,14 +339,20 @@ fn create_pgo_func_name_var<'ll, 'tcx>(
}
pub(crate) fn write_filenames_section_to_buffer<'a>(
filenames: impl IntoIterator<Item = &'a CString>,
filenames: impl IntoIterator<Item = &'a str>,
buffer: &RustString,
) {
let c_str_vec = filenames.into_iter().map(|cstring| cstring.as_ptr()).collect::<Vec<_>>();
let (pointers, lengths) = filenames
.into_iter()
.map(|s: &str| (s.as_ptr().cast(), s.len()))
.unzip::<_, _, Vec<_>, Vec<_>>();
unsafe {
llvm::LLVMRustCoverageWriteFilenamesSectionToBuffer(
c_str_vec.as_ptr(),
c_str_vec.len(),
pointers.as_ptr(),
pointers.len(),
lengths.as_ptr(),
lengths.len(),
buffer,
);
}

View File

@ -1704,6 +1704,8 @@ extern "C" {
pub fn LLVMRustCoverageWriteFilenamesSectionToBuffer(
Filenames: *const *const c_char,
FilenamesLen: size_t,
Lengths: *const size_t,
LengthsLen: size_t,
BufferOut: &RustString,
);

View File

@ -103,12 +103,20 @@ fromRust(LLVMRustCounterExprKind Kind) {
}
extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
const char* const Filenames[],
const char *const Filenames[],
size_t FilenamesLen,
const size_t *const Lengths,
size_t LengthsLen,
RustStringRef BufferOut) {
if (FilenamesLen != LengthsLen) {
report_fatal_error(
"Mismatched lengths in LLVMRustCoverageWriteFilenamesSectionToBuffer");
}
SmallVector<std::string,32> FilenameRefs;
FilenameRefs.reserve(FilenamesLen);
for (size_t i = 0; i < FilenamesLen; i++) {
FilenameRefs.push_back(std::string(Filenames[i]));
FilenameRefs.emplace_back(Filenames[i], Lengths[i]);
}
auto FilenamesWriter =
coverage::CoverageFilenamesSectionWriter(ArrayRef<std::string>(FilenameRefs));