Use string length when available when calling Stringpool. Compare
pointers first when looking up Stringpool entries.
This commit is contained in:
parent
2353d21439
commit
c0873094f5
5 changed files with 51 additions and 30 deletions
|
@ -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.
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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))
|
||||
{ }
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue