From 32b2fb82f2bd2aab582819cc3ed756133b1c5fbf Mon Sep 17 00:00:00 2001 From: Matt Loring Date: Wed, 20 Jul 2016 13:37:45 -0700 Subject: [PATCH] deps: backport a76d133 from v8 upstream Original commit message: Fix incorrect parameter to HasSufficientCapacity It takes the number of additional elements, not the total target capacity. Also, avoid right-shifting a negative integer as this is undefined in general BUG=v8:4909 R=verwaest@chromium.org Review-Url: https://codereview.chromium.org/2162333002 Cr-Commit-Position: refs/heads/master@{#37901} Fixes: https://github.com/nodejs/node/issues/6180 Ref: https://github.com/nodejs/node/pull/7883 PR-URL: https://github.com/nodejs/node/pull/7689 Reviewed-By: Matt Loring Reviewed-By: Ben Noordhuis --- deps/v8/src/objects.cc | 33 ++++++++++++++++++++++----------- deps/v8/src/objects.h | 3 +++ 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/deps/v8/src/objects.cc b/deps/v8/src/objects.cc index d16c8e408c30b4..9e2d07e263496b 100644 --- a/deps/v8/src/objects.cc +++ b/deps/v8/src/objects.cc @@ -13766,14 +13766,8 @@ Handle HashTable::EnsureCapacity( Isolate* isolate = table->GetIsolate(); int capacity = table->Capacity(); int nof = table->NumberOfElements() + n; - int nod = table->NumberOfDeletedElements(); - // Return if: - // 50% is still free after adding n elements and - // at most 50% of the free elements are deleted elements. - if (nod <= (capacity - nof) >> 1) { - int needed_free = nof >> 1; - if (nof + needed_free <= capacity) return table; - } + + if (table->HasSufficientCapacityToAdd(n)) return table; const int kMinCapacityForPretenure = 256; bool should_pretenure = pretenure == TENURED || @@ -13790,6 +13784,23 @@ Handle HashTable::EnsureCapacity( } +template +bool HashTable::HasSufficientCapacityToAdd( + int number_of_additional_elements) { + int capacity = Capacity(); + int nof = NumberOfElements() + number_of_additional_elements; + int nod = NumberOfDeletedElements(); + // Return true if: + // 50% is still free after adding number_of_additional_elements elements and + // at most 50% of the free elements are deleted elements. + if ((nof < capacity) && ((nod <= (capacity - nof) >> 1))) { + int needed_free = nof >> 1; + if (nof + needed_free <= capacity) return true; + } + return false; +} + + template Handle HashTable::Shrink(Handle table, Key key) { @@ -14827,7 +14838,7 @@ Dictionary::GenerateNewEnumerationIndices( } -template +template Handle Dictionary::EnsureCapacity( Handle dictionary, int n, Key key) { // Check whether there are enough enumeration indices to add n elements. @@ -15215,8 +15226,8 @@ Handle ObjectHashTable::Put(Handle table, } // If we're out of luck, we didn't get a GC recently, and so rehashing // isn't enough to avoid a crash. - int nof = table->NumberOfElements() + 1; - if (!table->HasSufficientCapacity(nof)) { + if (!table->HasSufficientCapacityToAdd(1)) { + int nof = table->NumberOfElements() + 1; int capacity = ObjectHashTable::ComputeCapacity(nof * 2); if (capacity > ObjectHashTable::kMaxCapacity) { for (size_t i = 0; i < 2; ++i) { diff --git a/deps/v8/src/objects.h b/deps/v8/src/objects.h index 83e103db510b89..1c5743eb838918 100644 --- a/deps/v8/src/objects.h +++ b/deps/v8/src/objects.h @@ -3114,6 +3114,9 @@ class HashTable : public HashTableBase { Key key, PretenureFlag pretenure = NOT_TENURED); + // Returns true if this table has sufficient capacity for adding n elements. + bool HasSufficientCapacityToAdd(int number_of_additional_elements); + // Sets the capacity of the hash table. void SetCapacity(int capacity) { // To scale a computed hash code to fit within the hash table, we