X-Git-Url: http://drtracing.org/?a=blobdiff_plain;f=gold%2Fstringpool.cc;h=d6fd7157bf0fbd53b21111dc7006a7343af2a26d;hb=c7ad08e6e5ff0768f5f0aeed12864a7bab588386;hp=b2738b3e4ffa7f4f78454bc6d0b43393594c6cc8;hpb=8851eccaec28f25f56fab5ba5d8ae44f71729975;p=deliverable%2Fbinutils-gdb.git diff --git a/gold/stringpool.cc b/gold/stringpool.cc index b2738b3e4f..d6fd7157bf 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -1,6 +1,6 @@ // stringpool.cc -- a string pool for gold -// Copyright 2006, 2007 Free Software Foundation, Inc. +// Copyright (C) 2006-2015 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -34,10 +34,15 @@ 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) + zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)), + addralign_(addralign) { + if (parameters->options_valid() + && parameters->options().optimize() >= 2 + && addralign <= sizeof(Stringpool_char)) + this->optimize_ = true; } template @@ -70,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; @@ -85,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 @@ -151,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 @@ -198,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 @@ -214,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, @@ -239,6 +216,26 @@ 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 non-zero length strings. + if (length != 0) + 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, @@ -248,7 +245,8 @@ Stringpool_template::add_with_length(const Stringpool_char* s, { typedef std::pair Insert_type; - const Key k = this->key_to_offset_.size(); + // We add 1 so that 0 is always invalid. + const Key k = this->key_to_offset_.size() + 1; if (!copy) { @@ -265,7 +263,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 { @@ -291,7 +289,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 @@ -394,21 +392,10 @@ Stringpool_template::set_string_offsets() // the strtab size, and gives a relatively small benefit (it's // typically rare for a symbol to be a suffix of another), we only // take the time to sort when the user asks for heavy optimization. - if (parameters->options().optimize() < 2) + 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]; - 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 { @@ -443,10 +430,10 @@ 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] = this_offset; + this->key_to_offset_[(*curr)->second - 1] = this_offset; last_offset = this_offset; } } @@ -475,7 +462,7 @@ Stringpool_template::get_offset_with_length( Hashkey hk(s, length); typename String_set_type::const_iterator p = this->string_set_.find(hk); if (p != this->string_set_.end()) - return this->key_to_offset_[p->second]; + return this->key_to_offset_[p->second - 1]; gold_unreachable(); } @@ -496,7 +483,7 @@ Stringpool_template::write_to_buffer( ++p) { const int len = (p->first.length + 1) * sizeof(Stringpool_char); - const section_offset_type offset = this->key_to_offset_[p->second]; + const section_offset_type offset = this->key_to_offset_[p->second - 1]; gold_assert(static_cast(offset) + len <= this->strtab_size_); memcpy(buffer + offset, p->first.string, len); @@ -521,7 +508,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());