From: Cary Coutant Date: Wed, 10 Mar 2010 17:37:11 +0000 (+0000) Subject: * fileread.cc (File_read::~File_read): Don't delete whole_file_view_. X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=a2a5469e7999a8e4e713e11bfd191c11a422e1e8;p=binutils-gdb.git * fileread.cc (File_read::~File_read): Don't delete whole_file_view_. (File_read::open[1]): Remove initial mapping of whole_file_view_. (File_read::open[2]): Add whole_file_view_ to list of views. (File_read::make_view): Remove test of whole_file_view_. (File_read::find_or_make_view): Create whole_file_view_ if necessary. (File_read::clear_views): Replace bool parameter with enum; adjust all callers. Don't delete views with permanent data; do delete cached views and views from archives if --no-keep-files-mapped is set. Set whole_file_view_ to NULL if clearing the corresponding view. * fileread.h (File_read::Clear_views_mode): New enum. (File_read::View::is_permanent_view): New method. (File_read::clear_views): Replace bool parameter with enum; adjust all callers. * options.h (General_options): Change keep_files_mapped option; add map_whole_files. * readsyms.cc (Add_symbols::run): Delete sd_ object before releasing the file. * reloc.cc (Scan_relocs::run): Delete rd_ object before releasing the file. --- diff --git a/gold/ChangeLog b/gold/ChangeLog index ec861cfe807..3c2e610c9d5 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,27 @@ +2010-03-10 Cary Coutant + + * fileread.cc (File_read::~File_read): Don't delete whole_file_view_. + (File_read::open[1]): Remove initial mapping of whole_file_view_. + (File_read::open[2]): Add whole_file_view_ to list of views. + (File_read::make_view): Remove test of whole_file_view_. + (File_read::find_or_make_view): Create whole_file_view_ if + necessary. + (File_read::clear_views): Replace bool parameter with enum; + adjust all callers. Don't delete views with permanent data; + do delete cached views and views from archives if + --no-keep-files-mapped is set. Set whole_file_view_ to NULL + if clearing the corresponding view. + * fileread.h (File_read::Clear_views_mode): New enum. + (File_read::View::is_permanent_view): New method. + (File_read::clear_views): Replace bool parameter + with enum; adjust all callers. + * options.h (General_options): Change keep_files_mapped option; + add map_whole_files. + * readsyms.cc (Add_symbols::run): Delete sd_ object before + releasing the file. + * reloc.cc (Scan_relocs::run): Delete rd_ object before releasing + the file. + 2010-03-10 David S. Miller * sparc.cc (Target_sparc::Scan::local): Accept R_SPARC_WPLT30. diff --git a/gold/fileread.cc b/gold/fileread.cc index 9f190990a60..1bfe9eb6335 100644 --- a/gold/fileread.cc +++ b/gold/fileread.cc @@ -115,9 +115,7 @@ File_read::~File_read() this->is_descriptor_opened_ = false; } this->name_.clear(); - this->clear_views(true); - if (this->whole_file_view_) - delete this->whole_file_view_; + this->clear_views(CLEAR_VIEWS_ALL); } // Open the file. @@ -144,23 +142,6 @@ File_read::open(const Task* task, const std::string& name) this->size_ = s.st_size; gold_debug(DEBUG_FILES, "Attempt to open %s succeeded", this->name_.c_str()); - - // Options may not yet be ready e.g. when reading a version - // script. We then default to --no-keep-files-mapped. - if (parameters->options_valid() - && parameters->options().keep_files_mapped()) - { - const unsigned char* contents = static_cast( - ::mmap(NULL, this->size_, PROT_READ, MAP_PRIVATE, - this->descriptor_, 0)); - if (contents == MAP_FAILED) - gold_fatal(_("%s: mmap failed: %s"), this->filename().c_str(), - strerror(errno)); - this->whole_file_view_ = new View(0, this->size_, contents, 0, false, - View::DATA_MMAPPED); - this->mapped_bytes_ += this->size_; - } - this->token_.add_writer(task); } @@ -180,6 +161,7 @@ File_read::open(const Task* task, const std::string& name, this->name_ = name; this->whole_file_view_ = new View(0, size, contents, 0, false, View::DATA_NOT_OWNED); + this->add_view(this->whole_file_view_); this->size_ = size; this->token_.add_writer(task); return true; @@ -226,7 +208,7 @@ File_read::release() // for releasing the descriptor. if (this->object_count_ <= 1) { - this->clear_views(false); + this->clear_views(CLEAR_VIEWS_NORMAL); if (this->is_descriptor_opened_) { release_descriptor(this->descriptor_, false); @@ -428,7 +410,7 @@ File_read::make_view(off_t start, section_size_type size, } File_read::View* v; - if (this->whole_file_view_ != NULL || byteshift != 0) + if (byteshift != 0) { unsigned char* p = new unsigned char[psize + byteshift]; memset(p, 0, byteshift); @@ -484,6 +466,15 @@ File_read::find_or_make_view(off_t offset, off_t start, byteshift = (target_size / 8) - byteshift; } + // If --map-whole-files is set, make sure we have a + // whole file view. Options may not yet be ready, e.g., + // when reading a version script. We then default to + // --no-keep-files-mapped. + if (this->whole_file_view_ == NULL + && parameters->options_valid() + && parameters->options().map_whole_files()) + this->whole_file_view_ = this->make_view(0, this->size_, 0, cache); + // Try to find a View with the required BYTESHIFT. File_read::View* vshifted; File_read::View* v = this->find_view(offset + start, size, @@ -691,25 +682,31 @@ File_read::clear_view_cache_marks() // the next object. void -File_read::clear_views(bool destroying) +File_read::clear_views(Clear_views_mode mode) { + bool keep_files_mapped = (parameters->options_valid() + && parameters->options().keep_files_mapped()); Views::iterator p = this->views_.begin(); while (p != this->views_.end()) { bool should_delete; - if (p->second->is_locked()) + if (p->second->is_locked() || p->second->is_permanent_view()) should_delete = false; - else if (destroying) + else if (mode == CLEAR_VIEWS_ALL) should_delete = true; - else if (p->second->should_cache()) + else if (p->second->should_cache() && keep_files_mapped) should_delete = false; - else if (this->object_count_ > 1 && p->second->accessed()) + else if (this->object_count_ > 1 + && p->second->accessed() + && mode != CLEAR_VIEWS_ARCHIVE) should_delete = false; else should_delete = true; if (should_delete) { + if (p->second == this->whole_file_view_) + this->whole_file_view_ = NULL; delete p->second; // map::erase invalidates only the iterator to the deleted @@ -720,7 +717,6 @@ File_read::clear_views(bool destroying) } else { - gold_assert(!destroying); p->second->clear_accessed(); ++p; } @@ -736,7 +732,7 @@ File_read::clear_views(bool destroying) } else { - gold_assert(!destroying); + gold_assert(mode != CLEAR_VIEWS_ALL); ++q; } } diff --git a/gold/fileread.h b/gold/fileread.h index 9933460d5ac..a81b5fe40f7 100644 --- a/gold/fileread.h +++ b/gold/fileread.h @@ -170,7 +170,7 @@ class File_read // interface, and it would be nice to have something more automatic. void clear_uncached_views() - { this->clear_views(false); } + { this->clear_views(CLEAR_VIEWS_ARCHIVE); } // A struct used to do a multiple read. struct Read_multiple_entry @@ -214,6 +214,17 @@ class File_read get_mtime(); private: + // Control for what views to clear. + enum Clear_views_mode + { + // Clear uncached views not used by an archive. + CLEAR_VIEWS_NORMAL, + // Clear all uncached views (including in an archive). + CLEAR_VIEWS_ARCHIVE, + // Clear all views (i.e., we're destroying the file). + CLEAR_VIEWS_ALL + }; + // This class may not be copied. File_read(const File_read&); File_read& operator=(const File_read&); @@ -303,6 +314,12 @@ class File_read accessed() const { return this->accessed_; } + // Returns TRUE if this view contains permanent data -- e.g., data that + // was supplied by the owner of the File object. + bool + is_permanent_view() const + { return this->data_ownership_ == DATA_NOT_OWNED; } + private: View(const View&); View& operator=(const View&); @@ -366,7 +383,7 @@ class File_read // Clear the file views. void - clear_views(bool); + clear_views(Clear_views_mode); // The size of a file page for buffering data. static const off_t page_size = 8192; diff --git a/gold/options.h b/gold/options.h index 7f35bd21db5..b725b040652 100644 --- a/gold/options.h +++ b/gold/options.h @@ -774,11 +774,14 @@ class General_options DEFINE_special(just_symbols, options::TWO_DASHES, '\0', N_("Read only symbol values from FILE"), N_("FILE")); - DEFINE_bool(keep_files_mapped, options::TWO_DASHES, '\0', + DEFINE_bool(map_whole_files, options::TWO_DASHES, '\0', sizeof(void*) >= 8, N_("Map whole files to memory (default on 64-bit hosts)"), N_("Map relevant file parts to memory (default on 32-bit " "hosts)")); + DEFINE_bool(keep_files_mapped, options::TWO_DASHES, '\0', true, + N_("Keep files mapped across passes (default)"), + N_("Release mapped files after each pass")); DEFINE_special(library, options::TWO_DASHES, 'l', N_("Search for library LIBNAME"), N_("LIBNAME")); diff --git a/gold/readsyms.cc b/gold/readsyms.cc index cd8814c70f5..2ca391cec60 100644 --- a/gold/readsyms.cc +++ b/gold/readsyms.cc @@ -470,6 +470,8 @@ Add_symbols::run(Workqueue*) if (!this->input_objects_->add_object(this->object_)) { + delete this->sd_; + this->sd_ = NULL; this->object_->release(); delete this->object_; } @@ -477,10 +479,10 @@ Add_symbols::run(Workqueue*) { this->object_->layout(this->symtab_, this->layout_, this->sd_); this->object_->add_symbols(this->symtab_, this->sd_, this->layout_); + delete this->sd_; + this->sd_ = NULL; this->object_->release(); } - delete this->sd_; - this->sd_ = NULL; } // Class Start_group. diff --git a/gold/reloc.cc b/gold/reloc.cc index 0061059827e..617573d4f67 100644 --- a/gold/reloc.cc +++ b/gold/reloc.cc @@ -179,9 +179,9 @@ void Scan_relocs::run(Workqueue*) { this->object_->scan_relocs(this->symtab_, this->layout_, this->rd_); - this->object_->release(); delete this->rd_; this->rd_ = NULL; + this->object_->release(); } // Return a debugging name for the task.