From 1aa37384696ad1fcec310e8d3c7955b0266f61d5 Mon Sep 17 00:00:00 2001 From: Doug Kwan Date: Tue, 16 Mar 2010 01:26:15 +0000 Subject: [PATCH] 2010-03-15 Doug Kwan * stringpool.cc (Stringpool_template::Stringpool_template): Initialize offset_. (Stringpool_template::new_key_offset): New method. (Stringpool_template::add_string): Assign offsets when adding new strings. (Stringpool_template::set_string_offsets): Do not set string offsets when not optimizing. * stringpool.h (Chunked_vector::Chunked_vector): Initialize data member size_. (Chunked_vector::clear): Clear size_. (Chunked_vector::reserve): Call reserve method of all Element_vectors. (Chunked_vector::size): Return size_. (Chunked_vector::push_back): Use size_ to find insert position. (Chunked_vector::size_): New data member. (Stringpool_template::set_no_zero_null): Assert string set is empty. (Stringpool_template::new_key_offset): New method declaration. (Stringpool_template::offset_): New data member. --- gold/ChangeLog | 20 ++++++++++++++++++++ gold/stringpool.cc | 41 +++++++++++++++++++++++++---------------- gold/stringpool.h | 46 +++++++++++++++++++++++++++++----------------- 3 files changed, 74 insertions(+), 33 deletions(-) diff --git a/gold/ChangeLog b/gold/ChangeLog index 4b20ad97e9..8a92513d46 100644 --- a/gold/ChangeLog +++ b/gold/ChangeLog @@ -1,3 +1,23 @@ +2010-03-15 Doug Kwan + + * stringpool.cc (Stringpool_template::Stringpool_template): Initialize + offset_. + (Stringpool_template::new_key_offset): New method. + (Stringpool_template::add_string): Assign offsets when adding new + strings. + (Stringpool_template::set_string_offsets): Do not set string offsets + when not optimizing. + * stringpool.h (Chunked_vector::Chunked_vector): Initialize data + member size_. + (Chunked_vector::clear): Clear size_. + (Chunked_vector::reserve): Call reserve method of all Element_vectors. + (Chunked_vector::size): Return size_. + (Chunked_vector::push_back): Use size_ to find insert position. + (Chunked_vector::size_): New data member. + (Stringpool_template::set_no_zero_null): Assert string set is empty. + (Stringpool_template::new_key_offset): New method declaration. + (Stringpool_template::offset_): New data member. + 2010-03-15 Rafael Espindola * readsyms.cc (Read_symbols::do_read_symbols): Update calls to diff --git a/gold/stringpool.cc b/gold/stringpool.cc index d9f40506eb..bbbe975989 100644 --- a/gold/stringpool.cc +++ b/gold/stringpool.cc @@ -36,7 +36,7 @@ namespace gold template Stringpool_template::Stringpool_template() : string_set_(), key_to_offset_(), strings_(), strtab_size_(0), - zero_null_(true), optimize_(false) + zero_null_(true), optimize_(false), offset_(0) { if (parameters->options_valid() && parameters->options().optimize() >= 2) this->optimize_ = true; @@ -232,6 +232,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) +{ + if (this->key_to_offset_.size() == 0) + this->offset_ = this->zero_null_ ? sizeof(Stringpool_char) : 0; + + section_offset_type offset; + if (this->zero_null_ && length == 0) + offset = 0; + else + { + offset = this->offset_; + this->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, @@ -259,7 +279,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 { @@ -285,7 +305,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 @@ -390,19 +410,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 { diff --git a/gold/stringpool.h b/gold/stringpool.h index 906ceaa17a..df3826d9eb 100644 --- a/gold/stringpool.h +++ b/gold/stringpool.h @@ -77,48 +77,50 @@ class Chunked_vector { public: Chunked_vector() - : chunks_() + : chunks_(), size_(0) { } // Clear the elements. void clear() - { this->chunks_.clear(); } + { + this->chunks_.clear(); + this->size_ = 0; + } // Reserve elements. void reserve(unsigned int n) { - n += chunk_size - 1; - while (n >= chunk_size) + if (n > this->chunks_.size() * chunk_size) { - this->chunks_.push_back(Element_vector()); - this->chunks_.back().reserve(chunk_size); - n -= chunk_size; + this->chunks_.resize((n + chunk_size - 1) / chunk_size); + // We need to call reserve() of all chunks since changing + // this->chunks_ casues Element_vectors to be copied. The + // reserved capacity of an Element_vector may be lost in copying. + for (size_t i = 0; i < this->chunks_.size(); ++i) + this->chunks_[i].reserve(chunk_size); } } // Get the number of elements. size_t size() const - { - if (this->chunks_.empty()) - return 0; - else - return ((this->chunks_.size() - 1) * chunk_size - + this->chunks_.back().size()); - } + { return this->size_; } // Push a new element on the back of the vector. void push_back(const Element& element) { - if (this->chunks_.empty() || this->chunks_.back().size() == chunk_size) + size_t chunk_index = this->size_ / chunk_size; + if (chunk_index >= this->chunks_.size()) { this->chunks_.push_back(Element_vector()); this->chunks_.back().reserve(chunk_size); + gold_assert(chunk_index < this->chunks_.size()); } - this->chunks_.back().push_back(element); + this->chunks_[chunk_index].push_back(element); + this->size_++; } // Return a reference to an entry in the vector. @@ -137,6 +139,7 @@ class Chunked_vector typedef std::vector Chunk_vector; Chunk_vector chunks_; + size_t size_; }; @@ -174,7 +177,10 @@ class Stringpool_template // should not be called for a proper ELF SHT_STRTAB section. void set_no_zero_null() - { this->zero_null_ = false; } + { + gold_assert(this->string_set_.empty()); + this->zero_null_ = false; + } // Indicate that this string pool should be optimized, even if not // running with -O2. @@ -282,6 +288,10 @@ class Stringpool_template char data[1]; }; + // Add a new key offset entry. + void + new_key_offset(size_t); + // Copy a string into the buffers, returning a canonical string. const Stringpool_char* add_string(const Stringpool_char*, size_t); @@ -372,6 +382,8 @@ class Stringpool_template bool zero_null_; // Whether to optimize the string table. bool optimize_; + // offset of the next string. + section_offset_type offset_; }; // The most common type of Stringpool. -- 2.34.1