X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gold%2Fstringpool.cc;h=02f0da9f3b19b5cbd2668501939573ebdda7bdc0;hb=d8e34cd3ac4303e82ff9de51b7909b6ffde5b9c6;hp=9ba505a0063232a9e72d17aeafc68dc244e43db4;hpb=c0873094f582f8dffda7eaea2ea21bd87f351570;p=platform%2Fupstream%2Fbinutils.git diff --git a/gold/stringpool.cc b/gold/stringpool.cc index 9ba505a..02f0da9 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-2014 Free Software Foundation, Inc. // Written by Ian Lance Taylor . // This file is part of gold. @@ -34,10 +34,13 @@ namespace gold { template -Stringpool_template::Stringpool_template() - : string_set_(), strings_(), strtab_size_(0), next_index_(1), - next_uncopied_key_(-1), zero_null_(true) +Stringpool_template::Stringpool_template(uint64_t addralign) + : string_set_(), key_to_offset_(), strings_(), strtab_size_(0), + zero_null_(true), optimize_(false), offset_(sizeof(Stringpool_char)), + addralign_(addralign) { + if (parameters->options_valid() && parameters->options().optimize() >= 2) + this->optimize_ = true; } template @@ -49,6 +52,7 @@ Stringpool_template::clear() ++p) delete[] reinterpret_cast(*p); this->strings_.clear(); + this->key_to_offset_.clear(); this->string_set_.clear(); } @@ -67,7 +71,12 @@ template void Stringpool_template::reserve(unsigned int n) { -#if defined(HAVE_TR1_UNORDERED_MAP) + this->key_to_offset_.reserve(n); + +#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; @@ -82,28 +91,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 @@ -148,28 +135,7 @@ size_t Stringpool_template::string_hash(const Stringpool_char* s, size_t length) { - // Fowler/Noll/Vo (FNV) hash (type FNV-1a). - const unsigned char* p = reinterpret_cast(s); - if (sizeof(size_t) > 4) - { - size_t result = static_cast(14695981039346656037ULL); - for (size_t i = 0; i < length * sizeof(Stringpool_char); ++i) - { - result ^= static_cast(*p++); - result *= 1099511628211ULL; - } - return result; - } - else - { - size_t result = 2166136261UL; - for (size_t i = 0; i < length * sizeof(Stringpool_char); ++i) - { - result ^= static_cast(*p++); - result *= 16777619UL; - } - return result; - } + return gold::string_hash(s, length); } // Add the string S to the list of canonical strings. Return a @@ -180,8 +146,7 @@ Stringpool_template::string_hash(const Stringpool_char* s, template const Stringpool_char* Stringpool_template::add_string(const Stringpool_char* s, - size_t len, - Key* pkey) + size_t len) { // We are in trouble if we've already computed the string offsets. gold_assert(this->strtab_size_ == 0); @@ -208,7 +173,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 @@ -218,30 +183,18 @@ Stringpool_template::add_string(const Stringpool_char* s, memset(ret + len - sizeof(Stringpool_char), 0, sizeof(Stringpool_char)); - if (pkey != NULL) - *pkey = psd->index * key_mult + psd->len; - psd->len += len; return reinterpret_cast(ret); } } - 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, sizeof(Stringpool_char)); psd->len = len; - psd->index = this->next_index_; - ++this->next_index_; - - if (pkey != NULL) - { - *pkey = psd->index * key_mult; - // Ensure there was no overflow. - gold_assert(*pkey / key_mult == psd->index); - } if (front) this->strings_.push_front(psd); @@ -261,6 +214,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, @@ -270,15 +243,15 @@ Stringpool_template::add_with_length(const Stringpool_char* s, { typedef std::pair Insert_type; + // We add 1 so that 0 is always invalid. + const Key k = this->key_to_offset_.size() + 1; + if (!copy) { // When we don't need to copy the string, we can call insert // directly. - const Key k = this->next_uncopied_key_; - const section_offset_type ozero = 0; - std::pair element(Hashkey(s, length), - std::make_pair(k, ozero)); + std::pair element(Hashkey(s, length), k); Insert_type ins = this->string_set_.insert(element); @@ -288,15 +261,15 @@ Stringpool_template::add_with_length(const Stringpool_char* s, { // We just added the string. The key value has now been // used. - --this->next_uncopied_key_; + this->new_key_offset(length); } else { - gold_assert(k != p->second.first); + gold_assert(k != p->second); } if (pkey != NULL) - *pkey = p->second.first; + *pkey = p->second; return p->first.string; } @@ -310,17 +283,17 @@ Stringpool_template::add_with_length(const Stringpool_char* s, if (p != this->string_set_.end()) { if (pkey != NULL) - *pkey = p->second.first; + *pkey = p->second; return p->first.string; } - Key k; - hk.string = this->add_string(s, length, &k); + 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 // adjust hk.hash_code or hk.length. - const section_offset_type ozero = 0; - std::pair element(hk, std::make_pair(k, ozero)); + std::pair element(hk, k); Insert_type ins = this->string_set_.insert(element); gold_assert(ins.second); @@ -341,7 +314,7 @@ Stringpool_template::find(const Stringpool_char* s, return NULL; if (pkey != NULL) - *pkey = p->second.first; + *pkey = p->second; return p->first.string; } @@ -417,20 +390,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->optimization_level() < 2) + if (!this->optimize_) { - for (typename String_set_type::iterator curr = this->string_set_.begin(); - curr != this->string_set_.end(); - curr++) - { - if (this->zero_null_ && curr->first.string[0] == 0) - curr->second.second = 0; - else - { - curr->second.second = offset; - offset += (curr->first.length + 1) * charsize; - } - } + // If we are not optimizing, the offsets are already assigned. + offset = this->offset_; } else { @@ -446,27 +409,30 @@ Stringpool_template::set_string_offsets() std::sort(v.begin(), v.end(), Stringpool_sort_comparison()); + section_offset_type last_offset = -1; for (typename std::vector::iterator last = v.end(), curr = v.begin(); curr != v.end(); last = curr++) { + section_offset_type this_offset; if (this->zero_null_ && (*curr)->first.string[0] == 0) - (*curr)->second.second = 0; + this_offset = 0; else if (last != v.end() && is_suffix((*curr)->first.string, (*curr)->first.length, (*last)->first.string, (*last)->first.length)) - (*curr)->second.second = ((*last)->second.second - + (((*last)->first.length - - (*curr)->first.length) - * charsize)); + this_offset = (last_offset + + (((*last)->first.length - (*curr)->first.length) + * charsize)); else { - (*curr)->second.second = 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; } } @@ -494,7 +460,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 p->second.second; + return this->key_to_offset_[p->second - 1]; gold_unreachable(); } @@ -515,9 +481,10 @@ Stringpool_template::write_to_buffer( ++p) { const int len = (p->first.length + 1) * sizeof(Stringpool_char); - gold_assert(static_cast(p->second.second) + len + const section_offset_type offset = this->key_to_offset_[p->second - 1]; + gold_assert(static_cast(offset) + len <= this->strtab_size_); - memcpy(buffer + p->second.second, p->first.string, len); + memcpy(buffer + offset, p->first.string, len); } } @@ -539,7 +506,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());