X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gold%2Fstringpool.cc;h=b31029a0f645cf10dca089a052b0395e5f28f03c;hb=28ce7b07473c33f2e4e380a861973d68ffe8017f;hp=05d1d68e5d5a3ceba1d98313fdc6f5eec060dd64;hpb=f7c8a183e8d2c83eddadddb3b473338abf30a1d5;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/stringpool.cc b/gold/stringpool.cc index 05d1d68e5d..b31029a0f6 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -1,6 +1,6 @@ // stringpool.cc -- a string pool for gold -// Copyright 2006, 2007, 2008 Free Software Foundation, Inc. +// Copyright (C) 2006-2019 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -34,11 +34,14 @@ namespace gold { template -Stringpool_template::Stringpool_template() +Stringpool_template::Stringpool_template(uint64_t addralign) : string_set_(), key_to_offset_(), strings_(), strtab_size_(0), - zero_null_(true), optimize_(false) + zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)), + addralign_(addralign) { - if (parameters->options_valid() && parameters->options().optimize() >= 2) + if (parameters->options_valid() + && parameters->options().optimize() >= 2 + && addralign <= sizeof(Stringpool_char)) this->optimize_ = true; } @@ -72,7 +75,10 @@ Stringpool_template::reserve(unsigned int n) { this->key_to_offset_.reserve(n); -#if defined(HAVE_TR1_UNORDERED_MAP) +#if defined(HAVE_UNORDERED_MAP) + this->string_set_.rehash(this->string_set_.size() + n); + return; +#elif defined(HAVE_TR1_UNORDERED_MAP) // rehash() implementation is broken in gcc 4.0.3's stl //this->string_set_.rehash(this->string_set_.size() + n); //return; @@ -87,28 +93,6 @@ Stringpool_template::reserve(unsigned int n) this->string_set_.swap(new_string_set); } -// Return the length of a string of arbitrary character type. - -template -size_t -Stringpool_template::string_length(const Stringpool_char* p) -{ - size_t len = 0; - for (; *p != 0; ++p) - ++len; - return len; -} - -// Specialize string_length for char. Maybe we could just use -// std::char_traits<>::length? - -template<> -inline size_t -Stringpool_template::string_length(const char* p) -{ - return strlen(p); -} - // Compare two strings of arbitrary character type for equality. template @@ -153,16 +137,7 @@ size_t Stringpool_template::string_hash(const Stringpool_char* s, size_t length) { - // This is the hash function used by the dynamic linker for - // DT_GNU_HASH entries. I compared this to a Fowler/Noll/Vo hash - // for a C++ program with 385,775 global symbols. This hash - // function was very slightly worse. However, it is much faster to - // compute. Overall wall clock time was a win. - const unsigned char* p = reinterpret_cast(s); - size_t h = 5381; - for (size_t i = 0; i < length * sizeof(Stringpool_char); ++i) - h = h * 33 + *p++; - return h; + return gold::string_hash(s, length); } // Add the string S to the list of canonical strings. Return a @@ -200,7 +175,7 @@ Stringpool_template::add_string(const Stringpool_char* s, alc = sizeof(Stringdata) + buffer_size; else { - Stringdata *psd = this->strings_.front(); + Stringdata* psd = this->strings_.front(); if (len > psd->alc - psd->len) alc = sizeof(Stringdata) + buffer_size; else @@ -216,7 +191,7 @@ Stringpool_template::add_string(const Stringpool_char* s, } } - Stringdata *psd = reinterpret_cast(new char[alc]); + Stringdata* psd = reinterpret_cast(new char[alc]); psd->alc = alc - sizeof(Stringdata); memcpy(psd->data, s, len - sizeof(Stringpool_char)); memset(psd->data + len - sizeof(Stringpool_char), 0, @@ -241,6 +216,25 @@ Stringpool_template::add(const Stringpool_char* s, bool copy, return this->add_with_length(s, string_length(s), copy, pkey); } +// Add a new key offset entry. + +template +void +Stringpool_template::new_key_offset(size_t length) +{ + section_offset_type offset; + if (this->zero_null_ && length == 0) + offset = 0; + else + { + offset = this->offset_; + // Align strings. + offset = align_address(offset, this->addralign_); + this->offset_ = offset + (length + 1) * sizeof(Stringpool_char); + } + this->key_to_offset_.push_back(offset); +} + template const Stringpool_char* Stringpool_template::add_with_length(const Stringpool_char* s, @@ -268,7 +262,7 @@ Stringpool_template::add_with_length(const Stringpool_char* s, { // We just added the string. The key value has now been // used. - this->key_to_offset_.push_back(0); + this->new_key_offset(length); } else { @@ -294,7 +288,7 @@ Stringpool_template::add_with_length(const Stringpool_char* s, return p->first.string; } - this->key_to_offset_.push_back(0); + this->new_key_offset(length); hk.string = this->add_string(s, length); // The contents of the string stay the same, so we don't need to @@ -399,19 +393,8 @@ Stringpool_template::set_string_offsets() // take the time to sort when the user asks for heavy optimization. if (!this->optimize_) { - for (typename String_set_type::iterator curr = this->string_set_.begin(); - curr != this->string_set_.end(); - curr++) - { - section_offset_type* poff = &this->key_to_offset_[curr->second - 1]; - if (this->zero_null_ && curr->first.string[0] == 0) - *poff = 0; - else - { - *poff = offset; - offset += (curr->first.length + 1) * charsize; - } - } + // If we are not optimizing, the offsets are already assigned. + offset = this->offset_; } else { @@ -437,6 +420,8 @@ Stringpool_template::set_string_offsets() if (this->zero_null_ && (*curr)->first.string[0] == 0) this_offset = 0; else if (last != v.end() + && ((((*curr)->first.length - (*last)->first.length) + % this->addralign_) == 0) && is_suffix((*curr)->first.string, (*curr)->first.length, (*last)->first.string, @@ -446,8 +431,8 @@ Stringpool_template::set_string_offsets() * charsize)); else { - this_offset = offset; - offset += ((*curr)->first.length + 1) * charsize; + this_offset = align_address(offset, this->addralign_); + offset = this_offset + ((*curr)->first.length + 1) * charsize; } this->key_to_offset_[(*curr)->second - 1] = this_offset; last_offset = this_offset; @@ -524,7 +509,7 @@ template void Stringpool_template::print_stats(const char* name) const { -#if defined(HAVE_TR1_UNORDERED_MAP) || defined(HAVE_EXT_HASH_MAP) +#if defined(HAVE_UNORDERED_MAP) || defined(HAVE_TR1_UNORDERED_MAP) || defined(HAVE_EXT_HASH_MAP) fprintf(stderr, _("%s: %s entries: %zu; buckets: %zu\n"), program_name, name, this->string_set_.size(), this->string_set_.bucket_count());