diff --git a/graph/Graph.cc b/graph/Graph.cc index 3ce7aec6..cf9b0438 100644 --- a/graph/Graph.cc +++ b/graph/Graph.cc @@ -657,7 +657,7 @@ Graph::makePrevPaths(Vertex *vertex, } PathVertexRep * -Graph::prevPaths(Vertex *vertex) const +Graph::prevPaths(Vertex *vertex) { return prev_paths_.pointer(vertex->prevPaths()); } diff --git a/include/sta/ArrayTable.hh b/include/sta/ArrayTable.hh index 959caabe..05c0e549 100644 --- a/include/sta/ArrayTable.hh +++ b/include/sta/ArrayTable.hh @@ -47,8 +47,8 @@ public: uint32_t count); // Grow as necessary and return pointer for id. TYPE *ensureId(ObjectId id); - TYPE *pointer(ObjectId id) const; - TYPE &ref(ObjectId id) const; + TYPE *pointer(ObjectId id); + TYPE &ref(ObjectId id); size_t size() const { return size_; } void clear(); @@ -66,11 +66,8 @@ private: BlockIdx free_block_idx_; // Index of next free object in free_block_idx_. ObjectIdx free_idx_; - // Don't use std::vector so growing blocks_ can be thread safe. - size_t blocks_size_; - size_t blocks_capacity_; - ArrayBlock *blocks_; - ArrayBlock *prev_blocks_; + std::vector> blocks_; + std::vector> prev_blocks_; // Linked list of free arrays indexed by array size. std::vector free_list_; static constexpr ObjectId idx_mask_ = block_size - 1; @@ -80,28 +77,24 @@ template ArrayTable::ArrayTable() : size_(0), free_block_idx_(block_idx_null), - free_idx_(object_idx_null), - blocks_size_(0), - blocks_capacity_(1024), - blocks_(new ArrayBlock[blocks_capacity_]), - prev_blocks_(nullptr) + free_idx_(object_idx_null) { + blocks_.reserve(1024); } template ArrayTable::~ArrayTable() { deleteBlocks(); - delete [] blocks_; - delete [] prev_blocks_; } template void ArrayTable::deleteBlocks() { - for (size_t i = 0; i < blocks_size_; i++) + for (size_t i = 0; i < blocks_.size(); i++) blocks_[i].free(); + blocks_.clear(); } template @@ -120,12 +113,12 @@ ArrayTable::make(uint32_t count, free_list_[count] = *head; } else { - ArrayBlock *block = blocks_size_ ? &blocks_[free_block_idx_] : nullptr; + ArrayBlock *block = blocks_.size() ? &blocks_[free_block_idx_] : nullptr; if ((free_idx_ == object_idx_null && free_block_idx_ == block_idx_null) || free_idx_ + count >= block->size()) { uint32_t size = block_size; - if (blocks_size_ == 0 + if (blocks_.size() == 0 // First block starts at idx 1. && count > block_size - 1) size = count + 1; @@ -145,7 +138,7 @@ template ArrayBlock * ArrayTable::makeBlock(uint32_t size) { - BlockIdx block_idx = blocks_size_; + BlockIdx block_idx = blocks_.size(); pushBlock(size); free_block_idx_ = block_idx; // ObjectId zero is reserved for object_id_null. @@ -157,21 +150,17 @@ template void ArrayTable::pushBlock(size_t size) { - auto blk_idx = blocks_size_++; - blocks_[blk_idx] = ArrayBlock(size); + blocks_.push_back(ArrayBlock(size)); - if (blocks_size_ >= block_id_max) + if (blocks_.size() >= block_id_max) criticalError(223, "max array table block count exceeded."); - if (blocks_size_ == blocks_capacity_) { - size_t new_capacity = blocks_capacity_ * 1.5; - ArrayBlock* new_blocks = new ArrayBlock[new_capacity]; - memcpy(new_blocks, blocks_, blocks_capacity_ * sizeof(ArrayBlock)); - if (prev_blocks_) - delete [] prev_blocks_; + if (blocks_.size() == blocks_.capacity()) { + prev_blocks_.reserve(blocks_.capacity() * 1.5); + const auto blocks_mid = blocks_.begin() + prev_blocks_.size(); + std::copy(blocks_.begin(), blocks_mid, prev_blocks_.begin()); + prev_blocks_.insert(prev_blocks_.end(), blocks_mid, blocks_.end()); // Preserve block array for other threads to reference. - prev_blocks_ = blocks_; - blocks_ = new_blocks; - blocks_capacity_ = new_capacity; + blocks_.swap(prev_blocks_); } } @@ -192,7 +181,7 @@ ArrayTable::destroy(ObjectId id, template TYPE * -ArrayTable::pointer(ObjectId id) const +ArrayTable::pointer(ObjectId id) { if (id == object_id_null) return nullptr; @@ -210,7 +199,7 @@ ArrayTable::ensureId(ObjectId id) BlockIdx blk_idx = id >> idx_bits; ObjectIdx obj_idx = id & idx_mask_; // Make enough blocks for blk_idx to be valid. - for (BlockIdx i = blocks_size_; i <= blk_idx; i++) { + for (BlockIdx i = blocks_.size(); i <= blk_idx; i++) { pushBlock(block_size); } return blocks_[blk_idx].pointer(obj_idx); @@ -218,7 +207,7 @@ ArrayTable::ensureId(ObjectId id) template TYPE & -ArrayTable::ref(ObjectId id) const +ArrayTable::ref(ObjectId id) { if (id == object_id_null) criticalError(222, "null ObjectId reference is undefined."); @@ -233,7 +222,6 @@ void ArrayTable::clear() { deleteBlocks(); - blocks_size_ = 0; size_ = 0; free_block_idx_ = block_idx_null; free_idx_ = object_idx_null; diff --git a/include/sta/Graph.hh b/include/sta/Graph.hh index 593e0f2f..d025470c 100644 --- a/include/sta/Graph.hh +++ b/include/sta/Graph.hh @@ -113,7 +113,7 @@ public: size_t requiredCount() const { return requireds_.size(); } PathVertexRep *makePrevPaths(Vertex *vertex, uint32_t count); - PathVertexRep *prevPaths(Vertex *vertex) const; + PathVertexRep *prevPaths(Vertex *vertex); void clearPrevPaths(); // Reported slew are the same as those in the liberty tables. // reported_slews = measured_slews / slew_derate_from_library