From cb29561284eaa37c5c8967e49a5db0a4064368bf Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 2 Jan 2008 23:48:49 +0000 Subject: Reduce the number of system calls. Use readv instead of pread. Do better handling of cached views. --- gold/reloc.cc | 46 +++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 43 insertions(+), 3 deletions(-) (limited to 'gold/reloc.cc') diff --git a/gold/reloc.cc b/gold/reloc.cc index f88151f..d361f16 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -22,6 +22,8 @@ #include "gold.h" +#include + #include "workqueue.h" #include "symtab.h" #include "output.h" @@ -159,6 +161,11 @@ Relocate_task::run(Workqueue*) { this->object_->relocate(this->options_, this->symtab_, this->layout_, this->of_); + + // This is normally the last thing we will do with an object, so + // uncache all views. + this->object_->clear_view_cache_marks(); + this->object_->release(); } @@ -376,8 +383,20 @@ Sized_relobj::do_relocate(const General_options& options, // Write out the local symbols. this->write_local_symbols(of, layout->sympool(), layout->dynpool()); + + // We should no longer need the local symbol values. + this->clear_local_symbols(); } +// Sort a Read_multiple vector by file offset. +struct Read_multiple_compare +{ + inline bool + operator()(const File_read::Read_multiple_entry& rme1, + const File_read::Read_multiple_entry& rme2) const + { return rme1.file_offset < rme2.file_offset; } +}; + // Write section data to the output file. PSHDRS points to the // section headers. Record the views in *PVIEWS for use when // relocating. @@ -386,11 +405,14 @@ template void Sized_relobj::write_sections(const unsigned char* pshdrs, Output_file* of, - Views* pviews) const + Views* pviews) { unsigned int shnum = this->shnum(); const std::vector& map_sections(this->map_to_output()); + File_read::Read_multiple rm; + bool is_sorted = true; + const unsigned char* p = pshdrs + This::shdr_size; for (unsigned int i = 1; i < shnum; ++i, p += This::shdr_size) { @@ -468,7 +490,13 @@ Sized_relobj::write_sections(const unsigned char* pshdrs, unsigned char* buffer = os->postprocessing_buffer(); view = buffer + view_start; if (output_offset != -1) - this->read(shdr.get_sh_offset(), view_size, view); + { + off_t sh_offset = shdr.get_sh_offset(); + if (!rm.empty() && rm.back().file_offset > sh_offset) + is_sorted = false; + rm.push_back(File_read::Read_multiple_entry(sh_offset, + view_size, view)); + } } else { @@ -477,7 +505,11 @@ Sized_relobj::write_sections(const unsigned char* pshdrs, else { view = of->get_output_view(view_start, view_size); - this->read(shdr.get_sh_offset(), view_size, view); + off_t sh_offset = shdr.get_sh_offset(); + if (!rm.empty() && rm.back().file_offset > sh_offset) + is_sorted = false; + rm.push_back(File_read::Read_multiple_entry(sh_offset, + view_size, view)); } } @@ -490,6 +522,14 @@ Sized_relobj::write_sections(const unsigned char* pshdrs, pvs->is_input_output_view = output_offset == -1; pvs->is_postprocessing_view = os->requires_postprocessing(); } + + // Actually read the data. + if (!rm.empty()) + { + if (!is_sorted) + std::sort(rm.begin(), rm.end(), Read_multiple_compare()); + this->read_multiple(rm); + } } // Relocate section data. VIEWS points to the section data as views -- cgit v1.1