From c0873094f582f8dffda7eaea2ea21bd87f351570 Mon Sep 17 00:00:00 2001 From: Ian Lance Taylor Date: Wed, 19 Dec 2007 00:29:28 +0000 Subject: [PATCH] Use string length when available when calling Stringpool. Compare pointers first when looking up Stringpool entries. --- gold/layout.cc | 2 +- gold/merge.cc | 12 ++++++++--- gold/stringpool.cc | 50 +++++++++++++++++++++++++++------------------- gold/stringpool.h | 14 +++++++++---- gold/symtab.cc | 3 ++- 5 files changed, 51 insertions(+), 30 deletions(-) diff --git a/gold/layout.cc b/gold/layout.cc index 45980d5145..231e2c9f41 100644 --- a/gold/layout.cc +++ b/gold/layout.cc @@ -269,7 +269,7 @@ Layout::layout(Sized_relobj* 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. diff --git a/gold/merge.cc b/gold/merge.cc index 65acf82721..2c76759db6 100644 --- a/gold/merge.cc +++ b/gold/merge.cc @@ -520,7 +520,8 @@ Output_merge_string::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::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(); diff --git a/gold/stringpool.cc b/gold/stringpool.cc index 3d8bfe6cad..9ba505a006 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -136,8 +136,9 @@ Stringpool_template::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 const Stringpool_char* Stringpool_template::add(const Stringpool_char* s, bool copy, Key* pkey) +{ + return this->add_with_length(s, string_length(s), copy, pkey); +} + +template +const Stringpool_char* +Stringpool_template::add_with_length(const Stringpool_char* s, + size_t length, + bool copy, + Key* pkey) { typedef std::pair Insert_type; @@ -266,7 +277,7 @@ Stringpool_template::add(const Stringpool_char* s, bool copy, const Key k = this->next_uncopied_key_; const section_offset_type ozero = 0; - std::pair element(Hashkey(s), + std::pair element(Hashkey(s, length), std::make_pair(k, ozero)); Insert_type ins = this->string_set_.insert(element); @@ -289,24 +300,12 @@ Stringpool_template::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 -const Stringpool_char* -Stringpool_template::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::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 element(hk, std::make_pair(k, ozero)); - typedef std::pair Insert_type; Insert_type ins = this->string_set_.insert(element); gold_assert(ins.second); @@ -482,9 +480,19 @@ template section_offset_type Stringpool_template::get_offset(const Stringpool_char* s) const +{ + return this->get_offset_with_length(s, string_length(s)); +} + +template +section_offset_type +Stringpool_template::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(); diff --git a/gold/stringpool.h b/gold/stringpool.h index 0da7921234..773bfc17af 100644 --- a/gold/stringpool.h +++ b/gold/stringpool.h @@ -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& 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)) { } diff --git a/gold/symtab.cc b/gold/symtab.cc index 2cab9801a5..afe47da228 100644 --- a/gold/symtab.cc +++ b/gold/symtab.cc @@ -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; -- 2.34.1