gdb/
[deliverable/binutils-gdb.git] / gold / fileread.cc
index bfab1a47f8e716f4e704f9e42bfd49e3bfe91380..36485a915be9b78d56f365ce5d81fb9b7a33576f 100644 (file)
@@ -1,6 +1,6 @@
 // fileread.cc -- read files for gold
 
-// Copyright 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
+// Copyright 2006, 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
 // Written by Ian Lance Taylor <iant@google.com>.
 
 // This file is part of gold.
@@ -24,6 +24,7 @@
 
 #include <cstring>
 #include <cerrno>
+#include <climits>
 #include <fcntl.h>
 #include <unistd.h>
 #include <sys/mman.h>
@@ -57,6 +58,17 @@ readv(int, const iovec*, int)
 namespace gold
 {
 
+// Class File_read.
+
+// A lock for the File_read static variables.
+static Lock* file_counts_lock = NULL;
+static Initialize_lock file_counts_initialize_lock(&file_counts_lock);
+
+// The File_read static variables.
+unsigned long long File_read::total_mapped_bytes;
+unsigned long long File_read::current_mapped_bytes;
+unsigned long long File_read::maximum_mapped_bytes;
+
 // Class File_read::View.
 
 File_read::View::~View()
@@ -70,7 +82,12 @@ File_read::View::~View()
     case DATA_MMAPPED:
       if (::munmap(const_cast<unsigned char*>(this->data_), this->size_) != 0)
         gold_warning(_("munmap failed: %s"), strerror(errno));
-      File_read::current_mapped_bytes -= this->size_;
+      if (!parameters->options_valid() || parameters->options().stats())
+       {
+         file_counts_initialize_lock.initialize();
+         Hold_optional_lock hl(file_counts_lock);
+         File_read::current_mapped_bytes -= this->size_;
+       }
       break;
     case DATA_NOT_OWNED:
       break;
@@ -100,15 +117,6 @@ File_read::View::is_locked()
 
 // Class File_read.
 
-// A lock for the File_read static variables.
-static Lock* file_counts_lock = NULL;
-static Initialize_lock file_counts_initialize_lock(&file_counts_lock);
-
-// The File_read static variables.
-unsigned long long File_read::total_mapped_bytes;
-unsigned long long File_read::current_mapped_bytes;
-unsigned long long File_read::maximum_mapped_bytes;
-
 File_read::~File_read()
 {
   gold_assert(this->token_.is_writable());
@@ -598,11 +606,22 @@ File_read::do_readv(off_t base, const Read_multiple& rm, size_t start,
               got, want, static_cast<long long>(base + first_offset));
 }
 
+// Portable IOV_MAX.
+
+#if !defined(HAVE_READV)
+#define GOLD_IOV_MAX 1
+#elif defined(IOV_MAX)
+#define GOLD_IOV_MAX IOV_MAX
+#else
+#define GOLD_IOV_MAX (File_read::max_readv_entries * 2)
+#endif
+
 // Read several pieces of data from the file.
 
 void
 File_read::read_multiple(off_t base, const Read_multiple& rm)
 {
+  static size_t iov_max = GOLD_IOV_MAX;
   size_t count = rm.size();
   size_t i = 0;
   while (i < count)
@@ -615,7 +634,7 @@ File_read::read_multiple(off_t base, const Read_multiple& rm)
       size_t j;
       for (j = i + 1; j < count; ++j)
        {
-         if (j - i >= File_read::max_readv_entries)
+         if (j - i >= File_read::max_readv_entries || j - i >= iov_max / 2)
            break;
          const Read_multiple_entry& j_entry(rm[j]);
          off_t j_off = j_entry.file_offset;
@@ -698,7 +717,9 @@ File_read::clear_views(Clear_views_mode mode)
        should_delete = false;
       else if (mode == CLEAR_VIEWS_ALL)
        should_delete = true;
-      else if (p->second->should_cache() && keep_files_mapped)
+      else if ((p->second->should_cache()
+               || p->second == this->whole_file_view_)
+              && keep_files_mapped)
        should_delete = false;
       else if (this->object_count_ > 1
               && p->second->accessed()
@@ -841,17 +862,19 @@ File_read::get_mtime()
 #endif
 }
 
-// Try to find a file in the extra search dirs. Returns true on success.
+// Try to find a file in the extra search dirs.  Returns true on success.
 
-static bool
-try_extra_search_path(int* pindex, const Input_file_argument* input_argument,
-                      std::string filename, std::string* found_name,
-                      std::string* namep) {
+bool
+Input_file::try_extra_search_path(int* pindex,
+                                 const Input_file_argument* input_argument,
+                                 std::string filename, std::string* found_name,
+                                 std::string* namep)
+{
   if (input_argument->extra_search_path() == NULL)
     return false;
 
   std::string name = input_argument->extra_search_path();
-  if (!IS_DIR_SEPARATOR (name[name.length() - 1]))
+  if (!IS_DIR_SEPARATOR(name[name.length() - 1]))
     name += '/';
   name += filename;
 
@@ -873,10 +896,11 @@ try_extra_search_path(int* pindex, const Input_file_argument* input_argument,
 // In each, we look in extra_search_path + library_path to find
 // the file location, rather than the current directory.
 
-static bool
-find_file(const Dirsearch& dirpath, int* pindex,
-          const Input_file_argument* input_argument, bool* is_in_sysroot,
-          std::string* found_name, std::string* namep)
+bool
+Input_file::find_file(const Dirsearch& dirpath, int* pindex,
+                     const Input_file_argument* input_argument,
+                     bool* is_in_sysroot,
+                     std::string* found_name, std::string* namep)
 {
   std::string name;
 
@@ -914,11 +938,13 @@ find_file(const Dirsearch& dirpath, int* pindex,
       else
        n1 = input_argument->name();
 
-      if (try_extra_search_path(pindex, input_argument, n1, found_name, namep))
+      if (Input_file::try_extra_search_path(pindex, input_argument, n1,
+                                           found_name, namep))
         return true;
 
-      if (!n2.empty() && try_extra_search_path(pindex, input_argument, n2,
-                                               found_name, namep))
+      if (!n2.empty() && Input_file::try_extra_search_path(pindex,
+                                                          input_argument, n2,
+                                                          found_name, namep))
         return true;
 
       // It is not in the extra_search_path.
@@ -958,6 +984,8 @@ find_file(const Dirsearch& dirpath, int* pindex,
                      input_argument->name());
           return false;
         }
+      *found_name = input_argument->name();
+      *namep = name;
       *pindex = index + 1;
       return true;
     }
@@ -966,11 +994,11 @@ find_file(const Dirsearch& dirpath, int* pindex,
 // Open the file.
 
 bool
-Input_file::open(const Dirsearch& dirpath, const Task* task, int *pindex)
+Input_file::open(const Dirsearch& dirpath, const Task* task, intpindex)
 {
   std::string name;
-  if (!find_file(dirpath, pindex, this->input_argument_, &this->is_in_sysroot_,
-                 &this->found_name_, &name))
+  if (!Input_file::find_file(dirpath, pindex, this->input_argument_,
+                            &this->is_in_sysroot_, &this->found_name_, &name))
     return false;
 
   // Now that we've figured out where the file lives, try to open it.
This page took 0.027023 seconds and 4 git commands to generate.