Use string length when available when calling Stringpool. Compare

pointers first when looking up Stringpool entries.
This commit is contained in:
Ian Lance Taylor 2007-12-19 00:29:28 +00:00
parent 2353d21439
commit c0873094f5
5 changed files with 51 additions and 30 deletions

View file

@ -269,7 +269,7 @@ Layout::layout(Sized_relobj<size, big_endian>* object, unsigned int shndx,
// Canonicalize the section name. // Canonicalize the section name.
Stringpool::Key name_key; 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 // Find the output section. The output section is selected based on
// the section name, type, and flags. // the section name, type, and flags.

View 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); section_size_type bytelen_with_null = ((pl - p) + 1) * sizeof(Char_type);
this->merged_strings_.push_back(Merged_string(object, shndx, i, str, 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(); this->merged_strings_.begin();
p != this->merged_strings_.end(); p != this->merged_strings_.end();
++p) ++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. // Save some memory.
this->merged_strings_.clear(); this->merged_strings_.clear();

View file

@ -136,8 +136,9 @@ Stringpool_template<Stringpool_char>::Stringpool_eq::operator()(
{ {
return (h1.hash_code == h2.hash_code return (h1.hash_code == h2.hash_code
&& h1.length == h2.length && h1.length == h2.length
&& memcmp(h1.string, h2.string, && (h1.string == h2.string
h1.length * sizeof(Stringpool_char)) == 0); || memcmp(h1.string, h2.string,
h1.length * sizeof(Stringpool_char)) == 0));
} }
// Hash function. The length is in characters, not bytes. // Hash function. The length is in characters, not bytes.
@ -256,6 +257,16 @@ template<typename Stringpool_char>
const Stringpool_char* const Stringpool_char*
Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy, Stringpool_template<Stringpool_char>::add(const Stringpool_char* s, bool copy,
Key* pkey) 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; 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 Key k = this->next_uncopied_key_;
const section_offset_type ozero = 0; 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)); std::make_pair(k, ozero));
Insert_type ins = this->string_set_.insert(element); 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 p->first.string;
} }
return this->add_prefix(s, string_length(s), pkey); // When we have to copy the string, we look it up twice in the hash
}
// 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
// table. The problem is that we can't insert S before we // table. The problem is that we can't insert S before we
// canonicalize it by copying it into the canonical list. The hash // canonicalize it by copying it into the canonical list. The hash
// code will only be computed once, so this isn't all that // code will only be computed once.
// expensive.
Hashkey hk(s, len); Hashkey hk(s, length);
typename String_set_type::const_iterator p = this->string_set_.find(hk); typename String_set_type::const_iterator p = this->string_set_.find(hk);
if (p != this->string_set_.end()) if (p != this->string_set_.end())
{ {
@ -316,14 +315,13 @@ Stringpool_template<Stringpool_char>::add_prefix(const Stringpool_char* s,
} }
Key k; 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 // The contents of the string stay the same, so we don't need to
// adjust hk.hash_code or hk.length. // adjust hk.hash_code or hk.length.
const section_offset_type ozero = 0; const section_offset_type ozero = 0;
std::pair<Hashkey, Hashval> element(hk, std::make_pair(k, ozero)); 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); Insert_type ins = this->string_set_.insert(element);
gold_assert(ins.second); gold_assert(ins.second);
@ -482,9 +480,19 @@ template<typename Stringpool_char>
section_offset_type section_offset_type
Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s) Stringpool_template<Stringpool_char>::get_offset(const Stringpool_char* s)
const 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); 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()) if (p != this->string_set_.end())
return p->second.second; return p->second.second;
gold_unreachable(); gold_unreachable();

View file

@ -108,9 +108,10 @@ class Stringpool_template
const Stringpool_char* const Stringpool_char*
add(const Stringpool_char* s, bool copy, Key* pkey); 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* 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 // If the string S is present in the pool, return the canonical
// string pointer. Otherwise, return NULL. If PKEY is not NULL, // 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. // Get the offset of the string S in the string table.
section_offset_type section_offset_type
get_offset(const std::basic_string<Stringpool_char>& s) const 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 // Get the size of the string table. This returns the number of
// bytes, not in units of Stringpool_char. // bytes, not in units of Stringpool_char.
@ -218,7 +224,7 @@ class Stringpool_template
// Note that these constructors are relatively expensive, because // Note that these constructors are relatively expensive, because
// they compute the hash code. // 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)) : string(s), length(string_length(s)), hash_code(string_hash(s, length))
{ } { }

View file

@ -630,7 +630,8 @@ Symbol_table::add_from_relobj(
else else
{ {
Stringpool::Key name_key; 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; bool def = false;
++ver; ++ver;