summaryrefslogtreecommitdiff
path: root/deps/v8/src/api.cc
diff options
context:
space:
mode:
authorYang Guo <yangguo@chromium.org>2018-11-20 08:59:38 +0100
committerMichaël Zasso <targos@protonmail.com>2018-11-24 12:02:13 +0100
commit70e2f9db13e6e7fd845f5329b76782906a50ce02 (patch)
treef702851563b7616f011d3c2943653f7aa77009ac /deps/v8/src/api.cc
parent9fe02af79425ae455e888ce2b99f86448d0053e6 (diff)
downloadandroid-node-v8-70e2f9db13e6e7fd845f5329b76782906a50ce02.tar.gz
android-node-v8-70e2f9db13e6e7fd845f5329b76782906a50ce02.tar.bz2
android-node-v8-70e2f9db13e6e7fd845f5329b76782906a50ce02.zip
deps: cherry-pick 88f8fe1 from upstream V8
Original commit message: Fix collection iterator preview with deleted entries We used to assume that we know the remaining entries returned by the iterator based on the current index. However, that is not accurate, since entries skipped by the current index could be deleted. In the new approach, we allocate conservatively and shrink the result. R=neis@chromium.org Bug: v8:8433 Change-Id: I38a3004dc3af292daabb454bb76f38d65ef437e8 Reviewed-on: https://chromium-review.googlesource.com/c/1325966 Commit-Queue: Yang Guo <yangguo@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#57360} Refs: https://github.com/v8/v8/commit/88f8fe19a863c6392bd296faf86c06eff2a41bc1 PR-URL: https://github.com/nodejs/node/pull/24514 Refs: https://github.com/nodejs/node/issues/24053 Reviewed-By: Michaël Zasso <targos@protonmail.com> Reviewed-By: Anna Henningsen <anna@addaleax.net> Reviewed-By: Gus Caplan <me@gus.host> Reviewed-By: Joyee Cheung <joyeec9h3@gmail.com>
Diffstat (limited to 'deps/v8/src/api.cc')
-rw-r--r--deps/v8/src/api.cc52
1 files changed, 27 insertions, 25 deletions
diff --git a/deps/v8/src/api.cc b/deps/v8/src/api.cc
index 8f8aaf7bc6..5ac9aec047 100644
--- a/deps/v8/src/api.cc
+++ b/deps/v8/src/api.cc
@@ -7103,30 +7103,30 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
i::Factory* factory = isolate->factory();
i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj),
isolate);
- if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
- int length = (table->NumberOfElements() - offset) *
- (kind == MapAsArrayKind::kEntries ? 2 : 1);
- i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
+ const bool collect_keys =
+ kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys;
+ const bool collect_values =
+ kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues;
+ int capacity = table->UsedCapacity();
+ int max_length =
+ (capacity - offset) * ((collect_keys && collect_values) ? 2 : 1);
+ i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- int capacity = table->UsedCapacity();
i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
- for (int i = 0; i < capacity; ++i) {
+ for (int i = offset; i < capacity; ++i) {
i::Object* key = table->KeyAt(i);
if (key == the_hole) continue;
- if (offset-- > 0) continue;
- if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys) {
- result->set(result_index++, key);
- }
- if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues) {
- result->set(result_index++, table->ValueAt(i));
- }
+ if (collect_keys) result->set(result_index++, key);
+ if (collect_values) result->set(result_index++, table->ValueAt(i));
}
}
- DCHECK_EQ(result_index, result->length());
- DCHECK_EQ(result_index, length);
- return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
+ DCHECK_GE(max_length, result_index);
+ if (result_index == 0) return factory->NewJSArray(0);
+ result->Shrink(isolate, result_index);
+ return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
+ result_index);
}
} // namespace
@@ -7211,24 +7211,26 @@ i::Handle<i::JSArray> SetAsArray(i::Isolate* isolate, i::Object* table_obj,
i::Factory* factory = isolate->factory();
i::Handle<i::OrderedHashSet> table(i::OrderedHashSet::cast(table_obj),
isolate);
- int length = table->NumberOfElements() - offset;
- if (length <= 0) return factory->NewJSArray(0);
- i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
+ // Elements skipped by |offset| may already be deleted.
+ int capacity = table->UsedCapacity();
+ int max_length = capacity - offset;
+ if (max_length == 0) return factory->NewJSArray(0);
+ i::Handle<i::FixedArray> result = factory->NewFixedArray(max_length);
int result_index = 0;
{
i::DisallowHeapAllocation no_gc;
- int capacity = table->UsedCapacity();
i::Oddball* the_hole = i::ReadOnlyRoots(isolate).the_hole_value();
- for (int i = 0; i < capacity; ++i) {
+ for (int i = offset; i < capacity; ++i) {
i::Object* key = table->KeyAt(i);
if (key == the_hole) continue;
- if (offset-- > 0) continue;
result->set(result_index++, key);
}
}
- DCHECK_EQ(result_index, result->length());
- DCHECK_EQ(result_index, length);
- return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
+ DCHECK_GE(max_length, result_index);
+ if (result_index == 0) return factory->NewJSArray(0);
+ result->Shrink(isolate, result_index);
+ return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS,
+ result_index);
}
} // namespace