Use string length when available when calling Stringpool. Compare
authorIan Lance Taylor <iant@google.com>
Wed, 19 Dec 2007 00:29:28 +0000 (00:29 +0000)
committerIan Lance Taylor <iant@google.com>
Wed, 19 Dec 2007 00:29:28 +0000 (00:29 +0000)
pointers first when looking up Stringpool entries.

gold/layout.cc
gold/merge.cc
gold/stringpool.cc
gold/stringpool.h
gold/symtab.cc

index 45980d514544dc86acdddb027a409bfc7f6c03c1..231e2c9f4146875b2516a589608ac940ab08e0bc 100644 (file)
@@ -269,7 +269,7 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
 
   // Canonicalize the section name.
   Stringpool::Key name_key;
-  name = this->namepool_.add_prefix(name, len, &name_key);
+  name = this->namepool_.add_with_length(name, len, true, &name_key);
 
   // Find the output section.  The output section is selected based on
   // the section name, type, and flags.
index 65acf827214a5635f42492091cd7a88258549a3a..2c76759db600d2bc691178bb46d9a8dd73cb8909 100644 (file)
@@ -520,7 +520,8 @@ Output_merge_string<Char_type>::do_add_input_section(Relobj* object,
            }
        }
 
-      const Char_type* str = this->stringpool_.add_prefix(p, pl - p, NULL);
+      const Char_type* str = this->stringpool_.add_with_length(p, pl - p, true,
+                                                              NULL);
 
       section_size_type bytelen_with_null = ((pl - p) + 1) * sizeof(Char_type);
       this->merged_strings_.push_back(Merged_string(object, shndx, i, str,
@@ -549,8 +550,13 @@ Output_merge_string<Char_type>::finalize_merged_data()
         this->merged_strings_.begin();
        p != this->merged_strings_.end();
        ++p)
-    this->add_mapping(p->object, p->shndx, p->offset, p->length,
-                     this->stringpool_.get_offset(p->string));
+    {
+      size_t charlen_without_null = (p->length / sizeof(Char_type)) - 1;
+      section_offset_type offset =
+       this->stringpool_.get_offset_with_length(p->string,
+                                                charlen_without_null);
+      this->add_mapping(p->object, p->shndx, p->offset, p->length, offset);
+    }
 
   // Save some memory.
   this->merged_strings_.clear();
index 3d8bfe6cad9f2971ad490d90104b4b92f372c533..9ba505a0063232a9e72d17aeafc68dc244e43db4 100644 (file)
@@ -136,8 +136,9 @@ Stringpool_template<Stringpool_char>::Stringpool_eq::operator()(
 {
   return (h1.hash_code == h2.hash_code
          && h1.length == h2.length
-         && memcmp(h1.string, h2.string,
-                   h1.length * sizeof(Stringpool_char)) == 0);
+         && (h1.string == h2.string
+             || memcmp(h1.string, h2.string,
+                       h1.length * sizeof(Stringpool_char)) == 0));
 }
 
 // Hash function.  The length is in characters, not bytes.
@@ -256,6 +257,16 @@ template<typename Stringpool_char>
 const Stringpool_char*
 Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
                                           Key* pkey)
+{
+  return this->add_with_length(s, string_length(s), copy, pkey);
+}
+
+template<typename Stringpool_char>
+const Stringpool_char*
+Stringpool_template<Stringpool_char>::add_with_length(const Stringpool_char* s,
+                                                     size_t length,
+                                                     bool copy,
+                                                     Key* pkey)
 {
   typedef std::pair<typename String_set_type::iterator, bool> Insert_type;
 
@@ -266,7 +277,7 @@ Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
 
       const Key k = this->next_uncopied_key_;
       const section_offset_type ozero = 0;
-      std::pair<Hashkey, Hashval> element(Hashkey(s),
+      std::pair<Hashkey, Hashval> element(Hashkey(s, length),
                                          std::make_pair(k, ozero));
 
       Insert_type ins = this->string_set_.insert(element);
@@ -289,24 +300,12 @@ Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
       return p->first.string;
     }
 
-  return this->add_prefix(s, string_length(s), pkey);
-}
-
-// Add a prefix of a string to a string pool.
-
-template<typename Stringpool_char>
-const Stringpool_char*
-Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
-                                                 size_t len,
-                                                 Key* pkey)
-{
-  // When adding an entry, this will look it up twice in the hash
+  // When we have to copy the string, we look it up twice in the hash
   // table.  The problem is that we can't insert S before we
   // canonicalize it by copying it into the canonical list. The hash
-  // code will only be computed once, so this isn't all that
-  // expensive.
+  // code will only be computed once.
 
-  Hashkey hk(s, len);
+  Hashkey hk(s, length);
   typename String_set_type::const_iterator p = this->string_set_.find(hk);
   if (p != this->string_set_.end())
     {
@@ -316,14 +315,13 @@ Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
     }
 
   Key k;
-  hk.string = this->add_string(s, len, &k);
+  hk.string = this->add_string(s, length, &k);
   // The contents of the string stay the same, so we don't need to
   // adjust hk.hash_code or hk.length.
 
   const section_offset_type ozero = 0;
   std::pair<Hashkey, Hashval> element(hk, std::make_pair(k, ozero));
 
-  typedef std::pair<typename String_set_type::iterator, bool> Insert_type;
   Insert_type ins = this->string_set_.insert(element);
   gold_assert(ins.second);
 
@@ -482,9 +480,19 @@ template<typename Stringpool_char>
 section_offset_type
 Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s)
   const
+{
+  return this->get_offset_with_length(s, string_length(s));
+}
+
+template<typename Stringpool_char>
+section_offset_type
+Stringpool_template<Stringpool_char>::get_offset_with_length(
+    const Stringpool_char* s,
+    size_t length) const
 {
   gold_assert(this->strtab_size_ != 0);
-  typename String_set_type::const_iterator p = this->string_set_.find(s);
+  Hashkey hk(s, length);
+  typename String_set_type::const_iterator p = this->string_set_.find(hk);
   if (p != this->string_set_.end())
     return p->second.second;
   gold_unreachable();
index 0da7921234b42ff84553d2bde415f261598aab14..773bfc17af1539202fc960e639a6cb82ed486928 100644 (file)
@@ -108,9 +108,10 @@ class Stringpool_template
   const Stringpool_char*
   add(const Stringpool_char* s, bool copy, Key* pkey);
 
-  // Add the prefix of length LEN of string S to the pool.
+  // Add string S of length LEN characters to the pool.  If COPY is
+  // true, S need not be null terminated.
   const Stringpool_char*
-  add_prefix(const Stringpool_char* s, size_t len, Key* pkey);
+  add_with_length(const Stringpool_char* s, size_t len, bool copy, Key* pkey);
 
   // If the string S is present in the pool, return the canonical
   // string pointer.  Otherwise, return NULL.  If PKEY is not NULL,
@@ -133,7 +134,12 @@ class Stringpool_template
   // Get the offset of the string S in the string table.
   section_offset_type
   get_offset(const std::basic_string<Stringpool_char>& s) const
-  { return this->get_offset(s.c_str()); }
+  { return this->get_offset_with_length(s.c_str(), s.size()); }
+
+  // Get the offset of string S, with length LENGTH characters, in the
+  // string table.
+  section_offset_type
+  get_offset_with_length(const Stringpool_char* s, size_t length) const;
 
   // Get the size of the string table.  This returns the number of
   // bytes, not in units of Stringpool_char.
@@ -218,7 +224,7 @@ class Stringpool_template
 
     // Note that these constructors are relatively expensive, because
     // they compute the hash code.
-    Hashkey(const Stringpool_char* s)
+    explicit Hashkey(const Stringpool_char* s)
       : string(s), length(string_length(s)), hash_code(string_hash(s, length))
     { }
 
index 2cab9801a56082932bc0a3b6867074494a3ca02e..afe47da22857352e40d93b7af47cc80ad389b7d1 100644 (file)
@@ -630,7 +630,8 @@ Symbol_table::add_from_relobj(
       else
        {
          Stringpool::Key name_key;
-         name = this->namepool_.add_prefix(name, ver - name, &name_key);
+         name = this->namepool_.add_with_length(name, ver - name, true,
+                                                &name_key);
 
          bool def = false;
          ++ver;