Commit 44770974 authored by Sigurd Schneider's avatar Sigurd Schneider Committed by Commit Bot

[runtime] Throw range error on too many properties

This change allows the KeyAccumulator to throw a range error if there
are too many properties to be enumerated.

This CL introduces extensive checks during key enumeration in the run-time,
and might introduce regressions. If so, feel free to revert.

Bug: chromium:918301
Change-Id: I6166c0b15f1a05eac7116a979f12ba4833d1d1b1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1545902
Auto-Submit: Sigurd Schneider <sigurds@chromium.org>
Reviewed-by: 's avatarUlan Degenbaev <ulan@chromium.org>
Reviewed-by: 's avatarToon Verwaest <verwaest@chromium.org>
Commit-Queue: Sigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#63430}
parent 5ba95354
......@@ -1583,6 +1583,11 @@ constexpr int kSmallOrderedHashMapMinCapacity = 4;
// has correct value range (see Issue 830 for more details).
enum StackFrameId { ID_MIN_VALUE = kMinInt, ID_MAX_VALUE = kMaxInt, NO_ID = 0 };
enum class ExceptionStatus : bool { kException = false, kSuccess = true };
V8_INLINE bool operator!(ExceptionStatus status) {
return !static_cast<bool>(status);
}
} // namespace internal
} // namespace v8
......
......@@ -485,6 +485,7 @@ namespace internal {
"Too many arguments in function call (only 65535 allowed)") \
T(TooManyParameters, \
"Too many parameters in function definition (only 65534 allowed)") \
T(TooManyProperties, "Too many properties to enumerate") \
T(TooManySpreads, \
"Literal containing too many nested spreads (up to 65534 allowed)") \
T(TooManyVariables, "Too many variables declared (only 4194303 allowed)") \
......
......@@ -686,16 +686,19 @@ Handle<SmallOrderedNameDictionary> Factory::NewSmallOrderedNameDictionary(
}
Handle<OrderedHashSet> Factory::NewOrderedHashSet() {
return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity);
return OrderedHashSet::Allocate(isolate(), OrderedHashSet::kMinCapacity)
.ToHandleChecked();
}
Handle<OrderedHashMap> Factory::NewOrderedHashMap() {
return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity);
return OrderedHashMap::Allocate(isolate(), OrderedHashMap::kMinCapacity)
.ToHandleChecked();
}
Handle<OrderedNameDictionary> Factory::NewOrderedNameDictionary() {
return OrderedNameDictionary::Allocate(isolate(),
OrderedNameDictionary::kMinCapacity);
OrderedNameDictionary::kMinCapacity)
.ToHandleChecked();
}
Handle<AccessorPair> Factory::NewAccessorPair() {
......
......@@ -5921,7 +5921,7 @@ void Heap::KeepDuringJob(Handle<JSReceiver> target) {
table =
handle(OrderedHashSet::cast(weak_refs_keep_during_job()), isolate());
}
table = OrderedHashSet::Add(isolate(), table, target);
table = OrderedHashSet::Add(isolate(), table, target).ToHandleChecked();
set_weak_refs_keep_during_job(*table);
}
......
......@@ -269,7 +269,11 @@ bool JsonStringifier::InitializeReplacer(Handle<Object> replacer) {
if (key.is_null()) continue;
// Object keys are internalized, so do it here.
key = factory()->InternalizeString(key);
set = OrderedHashSet::Add(isolate_, set, key);
MaybeHandle<OrderedHashSet> set_candidate =
OrderedHashSet::Add(isolate_, set, key);
if (!set_candidate.ToHandle(&set)) {
return false;
}
}
property_list_ = OrderedHashSet::ConvertToKeysArray(
isolate_, set, GetKeysConversion::kKeepNumbers);
......
......@@ -170,7 +170,8 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) BaseNameDictionary
// Collect the keys into the given KeyAccumulator, in ascending chronological
// order of property creation.
static void CollectKeysTo(Handle<Derived> dictionary, KeyAccumulator* keys);
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectKeysTo(
Handle<Derived> dictionary, KeyAccumulator* keys);
// Return the key indices sorted by its enumeration index.
static Handle<FixedArray> IterationIndices(Isolate* isolate,
......
......@@ -5,6 +5,7 @@
#ifndef V8_OBJECTS_ELEMENTS_INL_H_
#define V8_OBJECTS_ELEMENTS_INL_H_
#include "src/common/globals.h"
#include "src/objects/elements.h"
#include "src/handles/handles-inl.h"
......@@ -13,10 +14,11 @@
namespace v8 {
namespace internal {
inline void ElementsAccessor::CollectElementIndices(Handle<JSObject> object,
KeyAccumulator* keys) {
CollectElementIndices(object, handle(object->elements(), keys->isolate()),
keys);
V8_WARN_UNUSED_RESULT inline ExceptionStatus
ElementsAccessor::CollectElementIndices(Handle<JSObject> object,
KeyAccumulator* keys) {
return CollectElementIndices(
object, handle(object->elements(), keys->isolate()), keys);
}
inline MaybeHandle<FixedArray> ElementsAccessor::PrependElementIndices(
......
......@@ -68,6 +68,17 @@ namespace internal {
namespace {
#define RETURN_NOTHING_IF_NOT_SUCCESSFUL(call) \
do { \
if (!(call)) return Nothing<bool>(); \
} while (false)
#define RETURN_FAILURE_IF_NOT_SUCCESSFUL(call) \
do { \
ExceptionStatus status_enum_result = (call); \
if (!status_enum_result) return status_enum_result; \
} while (false)
static const int kPackedSizeNotKnown = -1;
enum Where { AT_START, AT_END };
......@@ -992,8 +1003,8 @@ class ElementsAccessorBase : public InternalElementsAccessor {
DCHECK_EQ(*nof_items, 0);
KeyAccumulator accumulator(isolate, KeyCollectionMode::kOwnOnly,
ALL_PROPERTIES);
Subclass::CollectElementIndicesImpl(
object, handle(object->elements(), isolate), &accumulator);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(Subclass::CollectElementIndicesImpl(
object, handle(object->elements(), isolate), &accumulator));
Handle<FixedArray> keys = accumulator.GetKeys();
int count = 0;
......@@ -1055,16 +1066,16 @@ class ElementsAccessorBase : public InternalElementsAccessor {
return Just(true);
}
void CollectElementIndices(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) final {
if (keys->filter() & ONLY_ALL_CAN_READ) return;
Subclass::CollectElementIndicesImpl(object, backing_store, keys);
V8_WARN_UNUSED_RESULT ExceptionStatus CollectElementIndices(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) final {
if (keys->filter() & ONLY_ALL_CAN_READ) return ExceptionStatus::kSuccess;
return Subclass::CollectElementIndicesImpl(object, backing_store, keys);
}
static void CollectElementIndicesImpl(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
DCHECK_NE(DICTIONARY_ELEMENTS, kind());
// Non-dictionary elements can't have all-can-read accessors.
uint32_t length = Subclass::GetMaxIndex(*object, *backing_store);
......@@ -1074,9 +1085,11 @@ class ElementsAccessorBase : public InternalElementsAccessor {
for (uint32_t i = 0; i < length; i++) {
if (Subclass::HasElementImpl(isolate, *object, i, *backing_store,
filter)) {
keys->AddKey(factory->NewNumberFromUint(i));
RETURN_FAILURE_IF_NOT_SUCCESSFUL(
keys->AddKey(factory->NewNumberFromUint(i)));
}
}
return ExceptionStatus::kSuccess;
}
static Handle<FixedArray> DirectCollectElementIndicesImpl(
......@@ -1189,10 +1202,11 @@ class ElementsAccessorBase : public InternalElementsAccessor {
return combined_keys;
}
void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) final {
Subclass::AddElementsToKeyAccumulatorImpl(receiver, accumulator, convert);
V8_WARN_UNUSED_RESULT ExceptionStatus AddElementsToKeyAccumulator(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) final {
return Subclass::AddElementsToKeyAccumulatorImpl(receiver, accumulator,
convert);
}
static uint32_t GetCapacityImpl(JSObject holder,
......@@ -1529,10 +1543,10 @@ class DictionaryElementsAccessor
return FilterKey(dictionary, entry, raw_key, filter);
}
static void CollectElementIndicesImpl(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
if (keys->filter() & SKIP_STRINGS) return;
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
if (keys->filter() & SKIP_STRINGS) return ExceptionStatus::kSuccess;
Isolate* isolate = keys->isolate();
Handle<NumberDictionary> dictionary =
Handle<NumberDictionary>::cast(backing_store);
......@@ -1555,8 +1569,9 @@ class DictionaryElementsAccessor
}
SortIndices(isolate, elements, insertion_index);
for (int i = 0; i < insertion_index; i++) {
keys->AddKey(elements->get(i));
RETURN_FAILURE_IF_NOT_SUCCESSFUL(keys->AddKey(elements->get(i)));
}
return ExceptionStatus::kSuccess;
}
static Handle<FixedArray> DirectCollectElementIndicesImpl(
......@@ -1581,9 +1596,9 @@ class DictionaryElementsAccessor
return list;
}
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) {
V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) {
Isolate* isolate = accumulator->isolate();
Handle<NumberDictionary> dictionary(
NumberDictionary::cast(receiver->elements()), isolate);
......@@ -1596,8 +1611,9 @@ class DictionaryElementsAccessor
DCHECK(!value.IsTheHole(isolate));
DCHECK(!value.IsAccessorPair());
DCHECK(!value.IsAccessorInfo());
accumulator->AddKey(value, convert);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(value, convert));
}
return ExceptionStatus::kSuccess;
}
static bool IncludesValueFastPath(Isolate* isolate, Handle<JSObject> receiver,
......@@ -2007,18 +2023,20 @@ class FastElementsAccessor : public ElementsAccessorBase<Subclass, KindTraits> {
return count;
}
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) {
V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) {
Isolate* isolate = accumulator->isolate();
Handle<FixedArrayBase> elements(receiver->elements(), isolate);
uint32_t length = Subclass::GetMaxNumberOfEntries(*receiver, *elements);
for (uint32_t i = 0; i < length; i++) {
if (IsFastPackedElementsKind(KindTraits::Kind) ||
HasEntryImpl(isolate, *elements, i)) {
accumulator->AddKey(Subclass::GetImpl(isolate, *elements, i), convert);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(
Subclass::GetImpl(isolate, *elements, i), convert));
}
}
return ExceptionStatus::kSuccess;
}
static void ValidateContents(JSObject holder, int length) {
......@@ -3006,16 +3024,17 @@ class TypedElementsAccessor
return AccessorClass::GetCapacityImpl(receiver, backing_store);
}
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) {
V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) {
Isolate* isolate = receiver->GetIsolate();
Handle<FixedArrayBase> elements(receiver->elements(), isolate);
uint32_t length = AccessorClass::GetCapacityImpl(*receiver, *elements);
for (uint32_t i = 0; i < length; i++) {
Handle<Object> value = AccessorClass::GetInternalImpl(receiver, i);
accumulator->AddKey(value, convert);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(value, convert));
}
return ExceptionStatus::kSuccess;
}
static Maybe<bool> CollectValuesOrEntriesImpl(
......@@ -3886,17 +3905,18 @@ class SloppyArgumentsElementsAccessor
ArgumentsAccessor::NumberOfElementsImpl(receiver, arguments);
}
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) {
V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) {
Isolate* isolate = accumulator->isolate();
Handle<FixedArrayBase> elements(receiver->elements(), isolate);
uint32_t length = GetCapacityImpl(*receiver, *elements);
for (uint32_t entry = 0; entry < length; entry++) {
if (!HasEntryImpl(isolate, *elements, entry)) continue;
Handle<Object> value = GetImpl(isolate, *elements, entry);
accumulator->AddKey(value, convert);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(value, convert));
}
return ExceptionStatus::kSuccess;
}
static bool HasEntryImpl(Isolate* isolate, FixedArrayBase parameters,
......@@ -3986,9 +4006,9 @@ class SloppyArgumentsElementsAccessor
UNREACHABLE();
}
static void CollectElementIndicesImpl(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
Isolate* isolate = keys->isolate();
uint32_t nof_indices = 0;
Handle<FixedArray> indices = isolate->factory()->NewFixedArray(
......@@ -3998,8 +4018,9 @@ class SloppyArgumentsElementsAccessor
ENUMERABLE_STRINGS, indices, &nof_indices);
SortIndices(isolate, indices, nof_indices);
for (uint32_t i = 0; i < nof_indices; i++) {
keys->AddKey(indices->get(i));
RETURN_FAILURE_IF_NOT_SUCCESSFUL(keys->AddKey(indices->get(i)));
}
return ExceptionStatus::kSuccess;
}
static Handle<FixedArray> DirectCollectElementIndicesImpl(
......@@ -4418,33 +4439,34 @@ class StringWrapperElementsAccessor
attributes);
}
static void AddElementsToKeyAccumulatorImpl(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) {
V8_WARN_UNUSED_RESULT static ExceptionStatus AddElementsToKeyAccumulatorImpl(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) {
Isolate* isolate = receiver->GetIsolate();
Handle<String> string(GetString(*receiver), isolate);
string = String::Flatten(isolate, string);
uint32_t length = static_cast<uint32_t>(string->length());
for (uint32_t i = 0; i < length; i++) {
accumulator->AddKey(
Handle<String> key =
isolate->factory()->LookupSingleCharacterStringFromCode(
string->Get(i)),
convert);
string->Get(i));
RETURN_FAILURE_IF_NOT_SUCCESSFUL(accumulator->AddKey(key, convert));
}
BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(receiver, accumulator,
convert);
return BackingStoreAccessor::AddElementsToKeyAccumulatorImpl(
receiver, accumulator, convert);
}
static void CollectElementIndicesImpl(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
V8_WARN_UNUSED_RESULT static ExceptionStatus CollectElementIndicesImpl(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) {
uint32_t length = GetString(*object).length();
Factory* factory = keys->isolate()->factory();
for (uint32_t i = 0; i < length; i++) {
keys->AddKey(factory->NewNumberFromUint(i));
RETURN_FAILURE_IF_NOT_SUCCESSFUL(
keys->AddKey(factory->NewNumberFromUint(i)));
}
BackingStoreAccessor::CollectElementIndicesImpl(object, backing_store,
keys);
return BackingStoreAccessor::CollectElementIndicesImpl(object,
backing_store, keys);
}
static void GrowCapacityAndConvertImpl(Handle<JSObject> object,
......@@ -4737,5 +4759,7 @@ Handle<JSArray> ElementsAccessor::Concat(Isolate* isolate, Arguments* args,
ElementsAccessor** ElementsAccessor::elements_accessors_ = nullptr;
#undef ELEMENTS_LIST
#undef RETURN_NOTHING_IF_NOT_SUCCESSFUL
#undef RETURN_FAILURE_IF_NOT_SUCCESSFUL
} // namespace internal
} // namespace v8
......@@ -69,12 +69,12 @@ class ElementsAccessor {
// Copy all indices that have elements from |object| into the given
// KeyAccumulator. For Dictionary-based element-kinds we filter out elements
// whose PropertyAttribute match |filter|.
virtual void CollectElementIndices(Handle<JSObject> object,
Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) = 0;
V8_WARN_UNUSED_RESULT virtual ExceptionStatus CollectElementIndices(
Handle<JSObject> object, Handle<FixedArrayBase> backing_store,
KeyAccumulator* keys) = 0;
inline void CollectElementIndices(Handle<JSObject> object,
KeyAccumulator* keys);
V8_WARN_UNUSED_RESULT inline ExceptionStatus CollectElementIndices(
Handle<JSObject> object, KeyAccumulator* keys);
virtual Maybe<bool> CollectValuesOrEntries(
Isolate* isolate, Handle<JSObject> object,
......@@ -90,9 +90,9 @@ class ElementsAccessor {
Handle<JSObject> object, Handle<FixedArray> keys,
GetKeysConversion convert, PropertyFilter filter = ALL_PROPERTIES);
virtual void AddElementsToKeyAccumulator(Handle<JSObject> receiver,
KeyAccumulator* accumulator,
AddKeyConversion convert) = 0;
V8_WARN_UNUSED_RESULT virtual ExceptionStatus AddElementsToKeyAccumulator(
Handle<JSObject> receiver, KeyAccumulator* accumulator,
AddKeyConversion convert) = 0;
virtual void TransitionElementsKind(Handle<JSObject> object,
Handle<Map> map) = 0;
......
......@@ -22,6 +22,17 @@
namespace v8 {
namespace internal {
#define RETURN_NOTHING_IF_NOT_SUCCESSFUL(call) \
do { \
if (!(call)) return Nothing<bool>(); \
} while (false)
#define RETURN_FAILURE_IF_NOT_SUCCESSFUL(call) \
do { \
ExceptionStatus status_enum_result = (call); \
if (!status_enum_result) return status_enum_result; \
} while (false)
namespace {
static bool ContainsOnlyValidKeys(Handle<FixedArray> array) {
......@@ -64,32 +75,39 @@ Handle<OrderedHashSet> KeyAccumulator::keys() {
return Handle<OrderedHashSet>::cast(keys_);
}
void KeyAccumulator::AddKey(Object key, AddKeyConversion convert) {
AddKey(handle(key, isolate_), convert);
ExceptionStatus KeyAccumulator::AddKey(Object key, AddKeyConversion convert) {
return AddKey(handle(key, isolate_), convert);
}
void KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) {
ExceptionStatus KeyAccumulator::AddKey(Handle<Object> key,
AddKeyConversion convert) {
if (filter_ == PRIVATE_NAMES_ONLY) {
if (!key->IsSymbol()) return;
if (!Symbol::cast(*key).is_private_name()) return;
if (!key->IsSymbol()) return ExceptionStatus::kSuccess;
if (!Symbol::cast(*key).is_private_name()) return ExceptionStatus::kSuccess;
} else if (key->IsSymbol()) {
if (filter_ & SKIP_SYMBOLS) return;
if (Symbol::cast(*key).is_private()) return;
if (filter_ & SKIP_SYMBOLS) return ExceptionStatus::kSuccess;
if (Symbol::cast(*key).is_private()) return ExceptionStatus::kSuccess;
} else if (filter_ & SKIP_STRINGS) {
return;
return ExceptionStatus::kSuccess;
}
if (IsShadowed(key)) return;
if (IsShadowed(key)) return ExceptionStatus::kSuccess;
if (keys_.is_null()) {
keys_ = OrderedHashSet::Allocate(isolate_, 16);
keys_ = OrderedHashSet::Allocate(isolate_, 16).ToHandleChecked();
}
uint32_t index;
if (convert == CONVERT_TO_ARRAY_INDEX && key->IsString() &&
Handle<String>::cast(key)->AsArrayIndex(&index)) {
key = isolate_->factory()->NewNumberFromUint(index);
}
Handle<OrderedHashSet> new_set = OrderedHashSet::Add(isolate(), keys(), key);
MaybeHandle<OrderedHashSet> new_set_candidate =
OrderedHashSet::Add(isolate(), keys(), key);
Handle<OrderedHashSet> new_set;
if (!new_set_candidate.ToHandle(&new_set)) {
THROW_NEW_ERROR_RETURN_VALUE(
isolate_, NewRangeError(MessageTemplate::kTooManyProperties),
ExceptionStatus::kException);
}
if (*new_set != *keys_) {
// The keys_ Set is converted directly to a FixedArray in GetKeys which can
// be left-trimmer. Hence the previous Set should not keep a pointer to the
......@@ -97,22 +115,24 @@ void KeyAccumulator::AddKey(Handle<Object> key, AddKeyConversion convert) {
keys_->set(OrderedHashSet::NextTableIndex(), Smi::kZero);
keys_ = new_set;
}
return ExceptionStatus::kSuccess;
}
void KeyAccumulator::AddKeys(Handle<FixedArray> array,
AddKeyConversion convert) {
ExceptionStatus KeyAccumulator::AddKeys(Handle<FixedArray> array,
AddKeyConversion convert) {
int add_length = array->length();
for (int i = 0; i < add_length; i++) {
Handle<Object> current(array->get(i), isolate_);
AddKey(current, convert);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(AddKey(current, convert));
}
return ExceptionStatus::kSuccess;
}
void KeyAccumulator::AddKeys(Handle<JSObject> array_like,
AddKeyConversion convert) {
ExceptionStatus KeyAccumulator::AddKeys(Handle<JSObject> array_like,
AddKeyConversion convert) {
DCHECK(array_like->IsJSArray() || array_like->HasSloppyArgumentsElements());
ElementsAccessor* accessor = array_like->GetElementsAccessor();
accessor->AddElementsToKeyAccumulator(array_like, this, convert);
return accessor->AddElementsToKeyAccumulator(array_like, this, convert);
}
MaybeHandle<FixedArray> FilterProxyKeys(KeyAccumulator* accumulator,
......@@ -162,7 +182,8 @@ Maybe<bool> KeyAccumulator::AddKeysFromJSProxy(Handle<JSProxy> proxy,
return Just(true);
}
}
AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(
AddKeys(keys, is_for_in_ ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT));
return Just(true);
}
......@@ -488,12 +509,10 @@ namespace {
enum IndexedOrNamed { kIndexed, kNamed };
void FilterForEnumerableProperties(Handle<JSReceiver> receiver,
Handle<JSObject> object,
Handle<InterceptorInfo> interceptor,
KeyAccumulator* accumulator,
Handle<JSObject> result,
IndexedOrNamed type) {
V8_WARN_UNUSED_RESULT ExceptionStatus FilterForEnumerableProperties(
Handle<JSReceiver> receiver, Handle<JSObject> object,
Handle<InterceptorInfo> interceptor, KeyAccumulator* accumulator,
Handle<JSObject> result, IndexedOrNamed type) {
DCHECK(result->IsJSArray() || result->HasSloppyArgumentsElements());
ElementsAccessor* accessor = result->GetElementsAccessor();
......@@ -521,10 +540,12 @@ void FilterForEnumerableProperties(Handle<JSReceiver> receiver,
int32_t value;
CHECK(attributes->ToInt32(&value));
if ((value & DONT_ENUM) == 0) {
accumulator->AddKey(element, DO_NOT_CONVERT);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(
accumulator->AddKey(element, DO_NOT_CONVERT));
}
}
}
return ExceptionStatus::kSuccess;
}
// Returns |true| on success, |nothing| on exception.
......@@ -551,11 +572,11 @@ Maybe<bool> CollectInterceptorKeysInternal(Handle<JSReceiver> receiver,
if ((accumulator->filter() & ONLY_ENUMERABLE) &&
!interceptor->query().IsUndefined(isolate)) {
FilterForEnumerableProperties(receiver, object, interceptor, accumulator,
result, type);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(FilterForEnumerableProperties(
receiver, object, interceptor, accumulator, result, type));
} else {
accumulator->AddKeys(
result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(accumulator->AddKeys(
result, type == kIndexed ? CONVERT_TO_ARRAY_INDEX : DO_NOT_CONVERT));
}
return Just(true);
}
......@@ -589,18 +610,17 @@ Maybe<bool> KeyAccumulator::CollectOwnElementIndices(
if (filter_ & SKIP_STRINGS || skip_indices_) return Just(true);
ElementsAccessor* accessor = object->GetElementsAccessor();
accessor->CollectElementIndices(object, this);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(
accessor->CollectElementIndices(object, this));
return CollectInterceptorKeys(receiver, object, this, kIndexed);
}
namespace {
template <bool skip_symbols>
int CollectOwnPropertyNamesInternal(Handle<JSObject> object,
KeyAccumulator* keys,
Handle<DescriptorArray> descs,
int start_index, int limit) {
base::Optional<int> CollectOwnPropertyNamesInternal(
Handle<JSObject> object, KeyAccumulator* keys,
Handle<DescriptorArray> descs, int start_index, int limit) {
int first_skipped = -1;
PropertyFilter filter = keys->filter();
KeyCollectionMode mode = keys->mode();
......@@ -633,7 +653,9 @@ int CollectOwnPropertyNamesInternal(Handle<JSObject> object,
if (is_shadowing_key) {
keys->AddShadowingKey(key);
} else {
keys->AddKey(key, DO_NOT_CONVERT);
if (keys->AddKey(key, DO_NOT_CONVERT) != ExceptionStatus::kSuccess) {
return base::Optional<int>();
}
}
}
return first_skipped;
......@@ -696,48 +718,50 @@ Maybe<bool> KeyAccumulator::CollectOwnPropertyNames(Handle<JSReceiver> receiver,
}
}
}
AddKeys(enum_keys, DO_NOT_CONVERT);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(AddKeys(enum_keys, DO_NOT_CONVERT));
} else {
if (object->HasFastProperties()) {
int limit = object->map().NumberOfOwnDescriptors();
Handle<DescriptorArray> descs(object->map().instance_descriptors(),
isolate_);
// First collect the strings,
int first_symbol =
base::Optional<int> first_symbol =
CollectOwnPropertyNamesInternal<true>(object, this, descs, 0, limit);
// then the symbols.
if (first_symbol != -1) {
CollectOwnPropertyNamesInternal<false>(object, this, descs,
first_symbol, limit);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(first_symbol);
if (first_symbol.value() != -1) {
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectOwnPropertyNamesInternal<false>(
object, this, descs, first_symbol.value(), limit));
}
} else if (object->IsJSGlobalObject()) {
GlobalDictionary::CollectKeysTo(
RETURN_NOTHING_IF_NOT_SUCCESSFUL(GlobalDictionary::CollectKeysTo(
handle(JSGlobalObject::cast(*object).global_dictionary(), isolate_),
this);
this));
} else {
NameDictionary::CollectKeysTo(
handle(object->property_dictionary(), isolate_), this);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(NameDictionary::CollectKeysTo(
handle(object->property_dictionary(), isolate_), this));
}
}
// Add the property keys from the interceptor.
return CollectInterceptorKeys(receiver, object, this, kNamed);
}
void KeyAccumulator::CollectPrivateNames(Handle<JSReceiver> receiver,
Handle<JSObject> object) {
ExceptionStatus KeyAccumulator::CollectPrivateNames(Handle<JSReceiver> receiver,
Handle<JSObject> object) {
if (object->HasFastProperties()) {
int limit = object->map().NumberOfOwnDescriptors();
Handle<DescriptorArray> descs(object->map().instance_descriptors(),
isolate_);
CollectOwnPropertyNamesInternal<false>(object, this, descs, 0, limit);
} else if (object->IsJSGlobalObject()) {
GlobalDictionary::CollectKeysTo(
RETURN_FAILURE_IF_NOT_SUCCESSFUL(GlobalDictionary::CollectKeysTo(
handle(JSGlobalObject::cast(*object).global_dictionary(), isolate_),
this);
this));
} else {
NameDictionary::CollectKeysTo(
handle(object->property_dictionary(), isolate_), this);
RETURN_FAILURE_IF_NOT_SUCCESSFUL(NameDictionary::CollectKeysTo(
handle(object->property_dictionary(), isolate_), this));
}
return ExceptionStatus::kSuccess;
}
Maybe<bool> KeyAccumulator::CollectAccessCheckInterceptorKeys(
......@@ -795,7 +819,7 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(Handle<JSReceiver> receiver,
filter_ = static_cast<PropertyFilter>(filter_ | ONLY_ALL_CAN_READ);
}
if (filter_ & PRIVATE_NAMES_ONLY) {
CollectPrivateNames(receiver, object);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectPrivateNames(receiver, object));
return Just(true);
}
......@@ -843,8 +867,8 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyKeys(Handle<JSReceiver> receiver,
Handle<JSProxy> proxy) {
STACK_CHECK(isolate_, Nothing<bool>());
if (filter_ == PRIVATE_NAMES_ONLY) {
NameDictionary::CollectKeysTo(
handle(proxy->property_dictionary(), isolate_), this);
RETURN_NOTHING_IF_NOT_SUCCESSFUL(NameDictionary::CollectKeysTo(
handle(proxy->property_dictionary(), isolate_), this));
return Just(true);
}
......@@ -1018,5 +1042,7 @@ Maybe<bool> KeyAccumulator::CollectOwnJSProxyTargetKeys(
return result;
}
#undef RETURN_NOTHING_IF_NOT_SUCCESSFUL
#undef RETURN_FAILURE_IF_NOT_SUCCESSFUL
} // namespace internal
} // namespace v8
......@@ -52,8 +52,8 @@ class KeyAccumulator final {
Handle<JSObject> object);
Maybe<bool> CollectOwnPropertyNames(Handle<JSReceiver> receiver,
Handle<JSObject> object);
void CollectPrivateNames(Handle<JSReceiver> receiver,
Handle<JSObject> object);
V8_WARN_UNUSED_RESULT ExceptionStatus
CollectPrivateNames(Handle<JSReceiver> receiver, Handle<JSObject> object);
Maybe<bool> CollectAccessCheckInterceptorKeys(
Handle<AccessCheckInfo> access_check_info, Handle<JSReceiver> receiver,
Handle<JSObject> object);
......@@ -65,10 +65,14 @@ class KeyAccumulator final {
static Handle<FixedArray> GetOwnEnumPropertyKeys(Isolate* isolate,
Handle<JSObject> object);
void AddKey(Object key, AddKeyConversion convert = DO_NOT_CONVERT);
void AddKey(Handle<Object> key, AddKeyConversion convert = DO_NOT_CONVERT);
void AddKeys(Handle<FixedArray> array, AddKeyConversion convert);
void AddKeys(Handle<JSObject> array_like, AddKeyConversion convert);
V8_WARN_UNUSED_RESULT ExceptionStatus
AddKey(Object key, AddKeyConversion convert = DO_NOT_CONVERT);
V8_WARN_UNUSED_RESULT ExceptionStatus
AddKey(Handle<Object> key, AddKeyConversion convert = DO_NOT_CONVERT);
V8_WARN_UNUSED_RESULT ExceptionStatus AddKeys(Handle<FixedArray> array,
AddKeyConversion convert);
V8_WARN_UNUSED_RESULT ExceptionStatus AddKeys(Handle<JSObject> array_like,
AddKeyConversion convert);
// Jump to the next level, pushing the current |levelLength_| to
// |levelLengths_| and adding a new list to |elements_|.
......
......@@ -7430,7 +7430,7 @@ Handle<FixedArray> BaseNameDictionary<Derived, Shape>::IterationIndices(
}
template <typename Derived, typename Shape>
void BaseNameDictionary<Derived, Shape>::CollectKeysTo(
ExceptionStatus BaseNameDictionary<Derived, Shape>::CollectKeysTo(
Handle<Derived> dictionary, KeyAccumulator* keys) {
Isolate* isolate = keys->isolate();
ReadOnlyRoots roots(isolate);
......@@ -7475,16 +7475,19 @@ void BaseNameDictionary<Derived, Shape>::CollectKeysTo(
has_seen_symbol = true;
continue;
}
keys->AddKey(key, DO_NOT_CONVERT);
ExceptionStatus status = keys->AddKey(key, DO_NOT_CONVERT);
if (!status) return status;
}
if (has_seen_symbol) {
for (int i = 0; i < array_size; i++) {
int index = Smi::ToInt(array->get(i));
Object key = dictionary->NameAt(index);
if (!key.IsSymbol()) continue;
keys->AddKey(key, DO_NOT_CONVERT);
ExceptionStatus status = keys->AddKey(key, DO_NOT_CONVERT);
if (!status) return status;
}
}
return ExceptionStatus::kSuccess;
}
// Backwards lookup (slow).
......@@ -8092,6 +8095,9 @@ HashTable<NameDictionary, NameDictionaryShape>::Shrink(Isolate* isolate,
Handle<NameDictionary>,
int additionalCapacity);
template void HashTable<GlobalDictionary, GlobalDictionaryShape>::Rehash(
ReadOnlyRoots roots);
Maybe<bool> JSFinalizationGroup::Cleanup(
Isolate* isolate, Handle<JSFinalizationGroup> finalization_group,
Handle<Object> cleanup) {
......
......@@ -14,7 +14,7 @@ namespace v8 {
namespace internal {
template <class Derived, int entrysize>
Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
MaybeHandle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
Isolate* isolate, int capacity, AllocationType allocation) {
// Capacity must be a power of two, since we depend on being able
// to divide and multiple by 2 (kLoadFactor) to derive capacity
......@@ -23,7 +23,7 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
// field of this object.
capacity = base::bits::RoundUpToPowerOfTwo32(Max(kMinCapacity, capacity));
if (capacity > MaxCapacity()) {
isolate->heap()->FatalProcessOutOfMemory("invalid table size");
return MaybeHandle<Derived>();
}
int num_buckets = capacity / kLoadFactor;
Handle<FixedArray> backing_store = isolate->factory()->NewFixedArrayWithMap(
......@@ -41,7 +41,7 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Allocate(
}
template <class Derived, int entrysize>
Handle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
MaybeHandle<Derived> OrderedHashTable<Derived, entrysize>::EnsureGrowable(
Isolate* isolate, Handle<Derived> table) {
DCHECK(!table->IsObsolete());
......@@ -64,7 +64,7 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Shrink(
int nof = table->NumberOfElements();
int capacity = table->Capacity();
if (nof >= (capacity >> 2)) return table;
return Derived::Rehash(isolate, table, capacity / 2);
return Derived::Rehash(isolate, table, capacity / 2).ToHandleChecked();
}
template <class Derived, int entrysize>
......@@ -72,10 +72,12 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Clear(
Isolate* isolate, Handle<Derived> table) {
DCHECK(!table->IsObsolete());
AllocationType allocation_type = Heap::InYoungGeneration(*table)
? AllocationType::kYoung
: AllocationType::kOld;
Handle<Derived> new_table =
Allocate(isolate, kMinCapacity,
Heap::InYoungGeneration(*table) ? AllocationType::kYoung
: AllocationType::kOld);
Allocate(isolate, kMinCapacity, allocation_type).ToHandleChecked();
table->SetNextTable(*new_table);
table->SetNumberOfDeletedElements(kClearedTableSentinel);
......@@ -120,9 +122,9 @@ int OrderedHashTable<Derived, entrysize>::FindEntry(Isolate* isolate,
return entry;
}
Handle<OrderedHashSet> OrderedHashSet::Add(Isolate* isolate,
Handle<OrderedHashSet> table,
Handle<Object> key) {
MaybeHandle<OrderedHashSet> OrderedHashSet::Add(Isolate* isolate,
Handle<OrderedHashSet> table,
Handle<Object> key) {
int hash = key->GetOrCreateHash(isolate).value();
int entry = table->HashToEntry(hash);
// Walk the chain of the bucket and try finding the key.
......@@ -133,7 +135,11 @@ Handle<OrderedHashSet> OrderedHashSet::Add(Isolate* isolate,
entry = table->NextChainEntry(entry);
}
table = OrderedHashSet::EnsureGrowable(isolate, table);
MaybeHandle<OrderedHashSet> table_candidate =
OrderedHashSet::EnsureGrowable(isolate, table);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
// Read the existing bucket values.
int bucket = table->HashToBucket(hash);
int previous_entry = table->HashToEntry(hash);
......@@ -186,14 +192,18 @@ HeapObject OrderedHashMap::GetEmpty(ReadOnlyRoots ro_roots) {
}
template <class Derived, int entrysize>
Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
MaybeHandle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
Isolate* isolate, Handle<Derived> table, int new_capacity) {
DCHECK(!table->IsObsolete());
Handle<Derived> new_table =
MaybeHandle<Derived> new_table_candidate =
Derived::Allocate(isolate, new_capacity,
Heap::InYoungGeneration(*table) ? AllocationType::kYoung
: AllocationType::kOld);
Handle<Derived> new_table;
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
int new_buckets = new_table->NumberOfBuckets();
......@@ -227,30 +237,33 @@ Handle<Derived> OrderedHashTable<Derived, entrysize>::Rehash(
new_table->SetNumberOfElements(nof);
table->SetNextTable(*new_table);
return new_table;
return new_table_candidate;
}
Handle<OrderedHashSet> OrderedHashSet::Rehash(Isolate* isolate,
Handle<OrderedHashSet> table,
int new_capacity) {
MaybeHandle<OrderedHashSet> OrderedHashSet::Rehash(Isolate* isolate,
Handle<OrderedHashSet> table,
int new_capacity) {
return OrderedHashTable<OrderedHashSet, 1>::Rehash(isolate, table,
new_capacity);
}
Handle<OrderedHashMap> OrderedHashMap::Rehash(Isolate* isolate,
Handle<OrderedHashMap> table,
int new_capacity) {
MaybeHandle<OrderedHashMap> OrderedHashMap::Rehash(Isolate* isolate,
Handle<OrderedHashMap> table,
int new_capacity) {
return OrderedHashTable<OrderedHashMap, 2>::Rehash(isolate, table,
new_capacity);
}
Handle<OrderedNameDictionary> OrderedNameDictionary::Rehash(
MaybeHandle<OrderedNameDictionary> OrderedNameDictionary::Rehash(
Isolate* isolate, Handle<OrderedNameDictionary> table, int new_capacity) {
Handle<OrderedNameDictionary> new_table =
MaybeHandle<OrderedNameDictionary> new_table_candidate =
OrderedHashTable<OrderedNameDictionary, 3>::Rehash(isolate, table,
new_capacity);
new_table->SetHash(table->Hash());
return new_table;
Handle<OrderedNameDictionary> new_table;
if (new_table_candidate.ToHandle(&new_table)) {
new_table->SetHash(table->Hash());
}
return new_table_candidate;
}
template <class Derived, int entrysize>
......@@ -286,10 +299,10 @@ Address OrderedHashMap::GetHash(Isolate* isolate, Address raw_key) {
return hash.ptr();
}
Handle<OrderedHashMap> OrderedHashMap::Add(Isolate* isolate,
Handle<OrderedHashMap> table,
Handle<Object> key,
Handle<Object> value) {
MaybeHandle<OrderedHashMap> OrderedHashMap::Add(Isolate* isolate,
Handle<OrderedHashMap> table,
Handle<Object> key,
Handle<Object> value) {
int hash = key->GetOrCreateHash(isolate).value();
int entry = table->HashToEntry(hash);
// Walk the chain of the bucket and try finding the key.
......@@ -304,7 +317,11 @@ Handle<OrderedHashMap> OrderedHashMap::Add(Isolate* isolate,
}
}
table = OrderedHashMap::EnsureGrowable(isolate, table);
MaybeHandle<OrderedHashMap> table_candidate =
OrderedHashMap::EnsureGrowable(isolate, table);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
// Read the existing bucket values.
int bucket = table->HashToBucket(hash);
int previous_entry = table->HashToEntry(hash);
......@@ -345,12 +362,16 @@ V8_EXPORT_PRIVATE int OrderedHashTable<OrderedNameDictionary, 3>::FindEntry(
return kNotFound;
}
Handle<OrderedNameDictionary> OrderedNameDictionary::Add(
MaybeHandle<OrderedNameDictionary> OrderedNameDictionary::Add(
Isolate* isolate, Handle<OrderedNameDictionary> table, Handle<Name> key,
Handle<Object> value, PropertyDetails details) {
DCHECK_EQ(kNotFound, table->FindEntry(isolate, *key));
table = OrderedNameDictionary::EnsureGrowable(isolate, table);
MaybeHandle<OrderedNameDictionary> table_candidate =
OrderedNameDictionary::EnsureGrowable(isolate, table);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
// Read the existing bucket values.
int hash = key->Hash();
int bucket = table->HashToBucket(hash);
......@@ -405,28 +426,31 @@ Handle<OrderedNameDictionary> OrderedNameDictionary::DeleteEntry(
return Shrink(isolate, table);
}
Handle<OrderedHashSet> OrderedHashSet::Allocate(Isolate* isolate, int capacity,
AllocationType allocation) {
MaybeHandle<OrderedHashSet> OrderedHashSet::Allocate(
Isolate* isolate, int capacity, AllocationType allocation) {
return OrderedHashTable<OrderedHashSet, 1>::Allocate(isolate, capacity,
allocation);
}
Handle<OrderedHashMap> OrderedHashMap::Allocate(Isolate* isolate, int capacity,
AllocationType allocation) {
MaybeHandle<OrderedHashMap> OrderedHashMap::Allocate(
Isolate* isolate, int capacity, AllocationType allocation) {
return OrderedHashTable<OrderedHashMap, 2>::Allocate(isolate, capacity,
allocation);
}
Handle<OrderedNameDictionary> OrderedNameDictionary::Allocate(
MaybeHandle<OrderedNameDictionary> OrderedNameDictionary::Allocate(
Isolate* isolate, int capacity, AllocationType allocation) {
Handle<OrderedNameDictionary> table =
MaybeHandle<OrderedNameDictionary> table_candidate =
OrderedHashTable<OrderedNameDictionary, 3>::Allocate(isolate, capacity,
allocation);
table->SetHash(PropertyArray::kNoHashSentinel);
return table;
Handle<OrderedNameDictionary> table;
if (table_candidate.ToHandle(&table)) {
table->SetHash(PropertyArray::kNoHashSentinel);
}
return table_candidate;
}
template V8_EXPORT_PRIVATE Handle<OrderedHashSet>
template V8_EXPORT_PRIVATE MaybeHandle<OrderedHashSet>
OrderedHashTable<OrderedHashSet, 1>::EnsureGrowable(
Isolate* isolate, Handle<OrderedHashSet> table);
......@@ -447,7 +471,7 @@ template V8_EXPORT_PRIVATE bool OrderedHashTable<OrderedHashSet, 1>::Delete(
template V8_EXPORT_PRIVATE int OrderedHashTable<OrderedHashSet, 1>::FindEntry(
Isolate* isolate, Object key);
template V8_EXPORT_PRIVATE Handle<OrderedHashMap>
template V8_EXPORT_PRIVATE MaybeHandle<OrderedHashMap>
OrderedHashTable<OrderedHashMap, 2>::EnsureGrowable(
Isolate* isolate, Handle<OrderedHashMap> table);
......@@ -472,7 +496,7 @@ template Handle<OrderedNameDictionary>
OrderedHashTable<OrderedNameDictionary, 3>::Shrink(
Isolate* isolate, Handle<OrderedNameDictionary> table);
template Handle<OrderedNameDictionary>
template MaybeHandle<OrderedNameDictionary>
OrderedHashTable<OrderedNameDictionary, 3>::EnsureGrowable(
Isolate* isolate, Handle<OrderedNameDictionary> table);
......@@ -912,8 +936,9 @@ SmallOrderedHashTable<SmallOrderedNameDictionary>::Shrink(
Isolate* isolate, Handle<SmallOrderedNameDictionary> table);
template <class SmallTable, class LargeTable>
Handle<HeapObject> OrderedHashTableHandler<SmallTable, LargeTable>::Allocate(
Isolate* isolate, int capacity) {
MaybeHandle<HeapObject>
OrderedHashTableHandler<SmallTable, LargeTable>::Allocate(Isolate* isolate,
int capacity) {
if (capacity < SmallTable::kMaxCapacity) {
return SmallTable::Allocate(isolate, capacity);
}
......@@ -921,13 +946,13 @@ Handle<HeapObject> OrderedHashTableHandler<SmallTable, LargeTable>::Allocate(
return LargeTable::Allocate(isolate, capacity);
}
template V8_EXPORT_PRIVATE Handle<HeapObject>
template V8_EXPORT_PRIVATE MaybeHandle<HeapObject>
OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet>::Allocate(
Isolate* isolate, int capacity);
template V8_EXPORT_PRIVATE Handle<HeapObject>
template V8_EXPORT_PRIVATE MaybeHandle<HeapObject>
OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::Allocate(
Isolate* isolate, int capacity);
template V8_EXPORT_PRIVATE Handle<HeapObject>
template V8_EXPORT_PRIVATE MaybeHandle<HeapObject>
OrderedHashTableHandler<SmallOrderedNameDictionary,
OrderedNameDictionary>::Allocate(Isolate* isolate,
int capacity);
......@@ -963,10 +988,14 @@ template bool
OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap>::HasKey(
Isolate* isolate, Handle<HeapObject> table, Handle<Object> key);
Handle<OrderedHashMap> OrderedHashMapHandler::AdjustRepresentation(
MaybeHandle<OrderedHashMap> OrderedHashMapHandler::AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedHashMap> table) {
Handle<OrderedHashMap> new_table =
MaybeHandle<OrderedHashMap> new_table_candidate =
OrderedHashMap::Allocate(isolate, OrderedHashTableMinSize);
Handle<OrderedHashMap> new_table;
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
......@@ -978,16 +1007,23 @@ Handle<OrderedHashMap> OrderedHashMapHandler::AdjustRepresentation(
if (key->IsTheHole(isolate)) continue;
Handle<Object> value = handle(
table->GetDataEntry(entry, SmallOrderedHashMap::kValueIndex), isolate);
new_table = OrderedHashMap::Add(isolate, new_table, key, value);
new_table_candidate = OrderedHashMap::Add(isolate, new_table, key, value);
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
}
return new_table;
return new_table_candidate;
}
Handle<OrderedHashSet> OrderedHashSetHandler::AdjustRepresentation(
MaybeHandle<OrderedHashSet> OrderedHashSetHandler::AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedHashSet> table) {
Handle<OrderedHashSet> new_table =
MaybeHandle<OrderedHashSet> new_table_candidate =
OrderedHashSet::Allocate(isolate, OrderedHashTableMinSize);
Handle<OrderedHashSet> new_table;
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
......@@ -997,17 +1033,24 @@ Handle<OrderedHashSet> OrderedHashSetHandler::AdjustRepresentation(
for (int entry = 0; entry < (nof + nod); ++entry) {
Handle<Object> key = handle(table->KeyAt(entry), isolate);
if (key->IsTheHole(isolate)) continue;
new_table = OrderedHashSet::Add(isolate, new_table, key);
new_table_candidate = OrderedHashSet::Add(isolate, new_table, key);
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
}
return new_table;
return new_table_candidate;
}
Handle<OrderedNameDictionary>
MaybeHandle<OrderedNameDictionary>
OrderedNameDictionaryHandler::AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedNameDictionary> table) {
Handle<OrderedNameDictionary> new_table =
MaybeHandle<OrderedNameDictionary> new_table_candidate =
OrderedNameDictionary::Allocate(isolate, OrderedHashTableMinSize);
Handle<OrderedNameDictionary> new_table;
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
int nof = table->NumberOfElements();
int nod = table->NumberOfDeletedElements();
......@@ -1019,17 +1062,20 @@ OrderedNameDictionaryHandler::AdjustRepresentation(
if (key->IsTheHole(isolate)) continue;
Handle<Object> value(table->ValueAt(entry), isolate);
PropertyDetails details = table->DetailsAt(entry);
new_table =
new_table_candidate =
OrderedNameDictionary::Add(isolate, new_table, key, value, details);
if (!new_table_candidate.ToHandle(&new_table)) {
return new_table_candidate;
}
}
return new_table;
return new_table_candidate;
}
Handle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Object> key,
Handle<Object> value) {
MaybeHandle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Object> key,
Handle<Object> value) {
if (table->IsSmallOrderedHashMap()) {
Handle<SmallOrderedHashMap> small_map =
Handle<SmallOrderedHashMap>::cast(table);
......@@ -1039,7 +1085,11 @@ Handle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate,
// We couldn't add to the small table, let's migrate to the
// big table.
table = OrderedHashMapHandler::AdjustRepresentation(isolate, small_map);
MaybeHandle<OrderedHashMap> table_candidate =
OrderedHashMapHandler::AdjustRepresentation(isolate, small_map);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
}
DCHECK(table->IsOrderedHashMap());
......@@ -1047,9 +1097,9 @@ Handle<HeapObject> OrderedHashMapHandler::Add(Isolate* isolate,
value);
}
Handle<HeapObject> OrderedHashSetHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Object> key) {
MaybeHandle<HeapObject> OrderedHashSetHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Object> key) {
if (table->IsSmallOrderedHashSet()) {
Handle<SmallOrderedHashSet> small_set =
Handle<SmallOrderedHashSet>::cast(table);
......@@ -1059,18 +1109,20 @@ Handle<HeapObject> OrderedHashSetHandler::Add(Isolate* isolate,
// We couldn't add to the small table, let's migrate to the
// big table.
table = OrderedHashSetHandler::AdjustRepresentation(isolate, small_set);
MaybeHandle<OrderedHashSet> table_candidate =
OrderedHashSetHandler::AdjustRepresentation(isolate, small_set);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
}
DCHECK(table->IsOrderedHashSet());
return OrderedHashSet::Add(isolate, Handle<OrderedHashSet>::cast(table), key);
}
Handle<HeapObject> OrderedNameDictionaryHandler::Add(Isolate* isolate,
Handle<HeapObject> table,
Handle<Name> key,
Handle<Object> value,
PropertyDetails details) {
MaybeHandle<HeapObject> OrderedNameDictionaryHandler::Add(
Isolate* isolate, Handle<HeapObject> table, Handle<Name> key,
Handle<Object> value, PropertyDetails details) {
if (table->IsSmallOrderedNameDictionary()) {
Handle<SmallOrderedNameDictionary> small_dict =
Handle<SmallOrderedNameDictionary>::cast(table);
......@@ -1081,8 +1133,11 @@ Handle<HeapObject> OrderedNameDictionaryHandler::Add(Isolate* isolate,
// We couldn't add to the small table, let's migrate to the
// big table.
table =
MaybeHandle<OrderedNameDictionary> table_candidate =
OrderedNameDictionaryHandler::AdjustRepresentation(isolate, small_dict);
if (!table_candidate.ToHandle(&table)) {
return table_candidate;
}
}
DCHECK(table->IsOrderedNameDictionary());
......
......@@ -64,8 +64,8 @@ class OrderedHashTable : public FixedArray {
public:
// Returns an OrderedHashTable (possibly |table|) with enough space
// to add at least one new element.
static Handle<Derived> EnsureGrowable(Isolate* isolate,
Handle<Derived> table);
static MaybeHandle<Derived> EnsureGrowable(Isolate* isolate,
Handle<Derived> table);
// Returns an OrderedHashTable (possibly |table|) that's shrunken
// if possible.
......@@ -197,11 +197,11 @@ class OrderedHashTable : public FixedArray {
protected:
// Returns an OrderedHashTable with a capacity of at least |capacity|.
static Handle<Derived> Allocate(
static MaybeHandle<Derived> Allocate(
Isolate* isolate, int capacity,
AllocationType allocation = AllocationType::kYoung);
static Handle<Derived> Rehash(Isolate* isolate, Handle<Derived> table,
int new_capacity);
static MaybeHandle<Derived> Rehash(Isolate* isolate, Handle<Derived> table,
int new_capacity);
void SetNumberOfBuckets(int num) {
set(NumberOfBucketsIndex(), Smi::FromInt(num));
......@@ -235,16 +235,16 @@ class V8_EXPORT_PRIVATE OrderedHashSet
public:
DECL_CAST(OrderedHashSet)
static Handle<OrderedHashSet> Add(Isolate* isolate,
Handle<OrderedHashSet> table,
Handle<Object> value);
static MaybeHandle<OrderedHashSet> Add(Isolate* isolate,
Handle<OrderedHashSet> table,
Handle<Object> value);
static Handle<FixedArray> ConvertToKeysArray(Isolate* isolate,
Handle<OrderedHashSet> table,
GetKeysConversion convert);
static Handle<OrderedHashSet> Rehash(Isolate* isolate,
Handle<OrderedHashSet> table,
int new_capacity);
static Handle<OrderedHashSet> Allocate(
static MaybeHandle<OrderedHashSet> Rehash(Isolate* isolate,
Handle<OrderedHashSet> table,
int new_capacity);
static MaybeHandle<OrderedHashSet> Allocate(
Isolate* isolate, int capacity,
AllocationType allocation = AllocationType::kYoung);
static HeapObject GetEmpty(ReadOnlyRoots ro_roots);
......@@ -262,16 +262,17 @@ class V8_EXPORT_PRIVATE OrderedHashMap
// Returns a value if the OrderedHashMap contains the key, otherwise
// returns undefined.
static Handle<OrderedHashMap> Add(Isolate* isolate,
Handle<OrderedHashMap> table,
Handle<Object> key, Handle<Object> value);
static MaybeHandle<OrderedHashMap> Add(Isolate* isolate,
Handle<OrderedHashMap> table,
Handle<Object> key,
Handle<Object> value);
static Handle<OrderedHashMap> Allocate(
static MaybeHandle<OrderedHashMap> Allocate(
Isolate* isolate, int capacity,
AllocationType allocation = AllocationType::kYoung);
static Handle<OrderedHashMap> Rehash(Isolate* isolate,
Handle<OrderedHashMap> table,
int new_capacity);
static MaybeHandle<OrderedHashMap> Rehash(Isolate* isolate,
Handle<OrderedHashMap> table,
int new_capacity);
Object ValueAt(int entry);
// This takes and returns raw Address values containing tagged Object
......@@ -656,7 +657,7 @@ class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) OrderedHashTableHandler {
public:
using Entry = int;
static Handle<HeapObject> Allocate(Isolate* isolate, int capacity);
static MaybeHandle<HeapObject> Allocate(Isolate* isolate, int capacity);
static bool Delete(Handle<HeapObject> table, Handle<Object> key);
static bool HasKey(Isolate* isolate, Handle<HeapObject> table,
Handle<Object> key);
......@@ -672,9 +673,9 @@ extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
class V8_EXPORT_PRIVATE OrderedHashMapHandler
: public OrderedHashTableHandler<SmallOrderedHashMap, OrderedHashMap> {
public:
static Handle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Object> key, Handle<Object> value);
static Handle<OrderedHashMap> AdjustRepresentation(
static MaybeHandle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Object> key, Handle<Object> value);
static MaybeHandle<OrderedHashMap> AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedHashMap> table);
};
......@@ -684,9 +685,9 @@ extern template class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
class V8_EXPORT_PRIVATE OrderedHashSetHandler
: public OrderedHashTableHandler<SmallOrderedHashSet, OrderedHashSet> {
public:
static Handle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Object> key);
static Handle<OrderedHashSet> AdjustRepresentation(
static MaybeHandle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Object> key);
static MaybeHandle<OrderedHashSet> AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedHashSet> table);
};
......@@ -695,7 +696,7 @@ class OrderedNameDictionary
public:
DECL_CAST(OrderedNameDictionary)
V8_EXPORT_PRIVATE static Handle<OrderedNameDictionary> Add(
V8_EXPORT_PRIVATE static MaybeHandle<OrderedNameDictionary> Add(
Isolate* isolate, Handle<OrderedNameDictionary> table, Handle<Name> key,
Handle<Object> value, PropertyDetails details);
......@@ -705,11 +706,11 @@ class OrderedNameDictionary
V8_EXPORT_PRIVATE static Handle<OrderedNameDictionary> DeleteEntry(
Isolate* isolate, Handle<OrderedNameDictionary> table, int entry);
static Handle<OrderedNameDictionary> Allocate(
static MaybeHandle<OrderedNameDictionary> Allocate(
Isolate* isolate, int capacity,
AllocationType allocation = AllocationType::kYoung);
static Handle<OrderedNameDictionary> Rehash(
static MaybeHandle<OrderedNameDictionary> Rehash(
Isolate* isolate, Handle<OrderedNameDictionary> table, int new_capacity);
// Returns the value for entry.
......@@ -745,9 +746,9 @@ class V8_EXPORT_PRIVATE OrderedNameDictionaryHandler
: public OrderedHashTableHandler<SmallOrderedNameDictionary,
OrderedNameDictionary> {
public:
static Handle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Name> key, Handle<Object> value,
PropertyDetails details);
static MaybeHandle<HeapObject> Add(Isolate* isolate, Handle<HeapObject> table,
Handle<Name> key, Handle<Object> value,
PropertyDetails details);
static Handle<HeapObject> Shrink(Isolate* isolate, Handle<HeapObject> table);
static Handle<HeapObject> DeleteEntry(Isolate* isolate,
......@@ -779,7 +780,7 @@ class V8_EXPORT_PRIVATE OrderedNameDictionaryHandler
static const int kNotFound = -1;
protected:
static Handle<OrderedNameDictionary> AdjustRepresentation(
static MaybeHandle<OrderedNameDictionary> AdjustRepresentation(
Isolate* isolate, Handle<SmallOrderedNameDictionary> table);
};
......
......@@ -25,7 +25,12 @@ RUNTIME_FUNCTION(Runtime_SetGrow) {
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSSet, holder, 0);
Handle<OrderedHashSet> table(OrderedHashSet::cast(holder->table()), isolate);
table = OrderedHashSet::EnsureGrowable(isolate, table);
MaybeHandle<OrderedHashSet> table_candidate =
OrderedHashSet::EnsureGrowable(isolate, table);
if (!table_candidate.ToHandle(&table)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kValueOutOfRange));
}
holder->set_table(*table);
return ReadOnlyRoots(isolate).undefined_value();
}
......@@ -56,7 +61,12 @@ RUNTIME_FUNCTION(Runtime_MapGrow) {
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSMap, holder, 0);
Handle<OrderedHashMap> table(OrderedHashMap::cast(holder->table()), isolate);
table = OrderedHashMap::EnsureGrowable(isolate, table);
MaybeHandle<OrderedHashMap> table_candidate =
OrderedHashMap::EnsureGrowable(isolate, table);
if (!table_candidate.ToHandle(&table)) {
THROW_NEW_ERROR_RETURN_FAILURE(
isolate, NewRangeError(MessageTemplate::kValueOutOfRange));
}
holder->set_table(*table);
return ReadOnlyRoots(isolate).undefined_value();
}
......
......@@ -509,14 +509,14 @@ TEST(OrderedHashTableInsertion) {
Handle<Smi> key1(Smi::FromInt(1), isolate);
Handle<Smi> value1(Smi::FromInt(1), isolate);
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key1));
map = OrderedHashMap::Add(isolate, map, key1, value1);
map = OrderedHashMap::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
CHECK(OrderedHashMap::HasKey(isolate, *map, *key1));
// Add existing key.
map = OrderedHashMap::Add(isolate, map, key1, value1);
map = OrderedHashMap::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -525,14 +525,14 @@ TEST(OrderedHashTableInsertion) {
Handle<String> key2 = factory->NewStringFromAsciiChecked("foo");
Handle<String> value = factory->NewStringFromAsciiChecked("bar");
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key2));
map = OrderedHashMap::Add(isolate, map, key2, value);
map = OrderedHashMap::Add(isolate, map, key2, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
CHECK(OrderedHashMap::HasKey(isolate, *map, *key1));
CHECK(OrderedHashMap::HasKey(isolate, *map, *key2));
map = OrderedHashMap::Add(isolate, map, key2, value);
map = OrderedHashMap::Add(isolate, map, key2, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
......@@ -541,7 +541,7 @@ TEST(OrderedHashTableInsertion) {
Handle<Symbol> key3 = factory->NewSymbol();
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key3));
map = OrderedHashMap::Add(isolate, map, key3, value);
map = OrderedHashMap::Add(isolate, map, key3, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(3, map->NumberOfElements());
......@@ -549,7 +549,7 @@ TEST(OrderedHashTableInsertion) {
CHECK(OrderedHashMap::HasKey(isolate, *map, *key2));
CHECK(OrderedHashMap::HasKey(isolate, *map, *key3));
map = OrderedHashMap::Add(isolate, map, key3, value);
map = OrderedHashMap::Add(isolate, map, key3, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(3, map->NumberOfElements());
......@@ -559,7 +559,7 @@ TEST(OrderedHashTableInsertion) {
Handle<Object> key4 = factory->NewHeapNumber(42.0);
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key4));
map = OrderedHashMap::Add(isolate, map, key4, value);
map = OrderedHashMap::Add(isolate, map, key4, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(4, map->NumberOfElements());
......@@ -568,7 +568,7 @@ TEST(OrderedHashTableInsertion) {
CHECK(OrderedHashMap::HasKey(isolate, *map, *key3));
CHECK(OrderedHashMap::HasKey(isolate, *map, *key4));
map = OrderedHashMap::Add(isolate, map, key4, value);
map = OrderedHashMap::Add(isolate, map, key4, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(4, map->NumberOfElements());
......@@ -587,7 +587,7 @@ TEST(OrderedHashMapDuplicateHashCode) {
Handle<OrderedHashMap> map = factory->NewOrderedHashMap();
Handle<JSObject> key1 = factory->NewJSObjectWithNullProto();
Handle<JSObject> value = factory->NewJSObjectWithNullProto();
map = OrderedHashMap::Add(isolate, map, key1, value);
map = OrderedHashMap::Add(isolate, map, key1, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -596,7 +596,7 @@ TEST(OrderedHashMapDuplicateHashCode) {
Handle<JSObject> key2 = factory->NewJSObjectWithNullProto();
CopyHashCode(key1, key2);
map = OrderedHashMap::Add(isolate, map, key2, value);
map = OrderedHashMap::Add(isolate, map, key2, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
......@@ -627,7 +627,7 @@ TEST(OrderedHashMapDeletion) {
CHECK_EQ(0, map->NumberOfDeletedElements());
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key1));
map = OrderedHashMap::Add(isolate, map, key1, value1);
map = OrderedHashMap::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -642,7 +642,7 @@ TEST(OrderedHashMapDeletion) {
CHECK_EQ(1, map->NumberOfDeletedElements());
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key1));
map = OrderedHashMap::Add(isolate, map, key1, value1);
map = OrderedHashMap::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -651,7 +651,7 @@ TEST(OrderedHashMapDeletion) {
Handle<String> key2 = factory->NewStringFromAsciiChecked("foo");
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key2));
map = OrderedHashMap::Add(isolate, map, key2, value);
map = OrderedHashMap::Add(isolate, map, key2, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(2, map->NumberOfElements());
......@@ -660,7 +660,7 @@ TEST(OrderedHashMapDeletion) {
Handle<Symbol> key3 = factory->NewSymbol();
CHECK(!OrderedHashMap::HasKey(isolate, *map, *key3));
map = OrderedHashMap::Add(isolate, map, key3, value);
map = OrderedHashMap::Add(isolate, map, key3, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(3, map->NumberOfElements());
......@@ -709,7 +709,7 @@ TEST(OrderedHashMapDeletion) {
// Delete non existent key from non empty hash table
map = OrderedHashMap::Shrink(isolate, map);
map = OrderedHashMap::Add(isolate, map, key1, value);
map = OrderedHashMap::Add(isolate, map, key1, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -858,7 +858,7 @@ TEST(OrderedHashMapDuplicateHashCodeDeletion) {
Handle<OrderedHashMap> map = factory->NewOrderedHashMap();
Handle<JSObject> key1 = factory->NewJSObjectWithNullProto();
Handle<JSObject> value = factory->NewJSObjectWithNullProto();
map = OrderedHashMap::Add(isolate, map, key1, value);
map = OrderedHashMap::Add(isolate, map, key1, value).ToHandleChecked();
Verify(isolate, map);
CHECK_EQ(2, map->NumberOfBuckets());
CHECK_EQ(1, map->NumberOfElements());
......@@ -928,7 +928,7 @@ TEST(OrderedHashSetDeletion) {
CHECK_EQ(0, set->NumberOfDeletedElements());
CHECK(!OrderedHashSet::HasKey(isolate, *set, *key1));
set = OrderedHashSet::Add(isolate, set, key1);
set = OrderedHashSet::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
......@@ -943,7 +943,7 @@ TEST(OrderedHashSetDeletion) {
CHECK_EQ(1, set->NumberOfDeletedElements());
CHECK(!OrderedHashSet::HasKey(isolate, *set, *key1));
set = OrderedHashSet::Add(isolate, set, key1);
set = OrderedHashSet::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
......@@ -952,7 +952,7 @@ TEST(OrderedHashSetDeletion) {
Handle<String> key2 = factory->NewStringFromAsciiChecked("foo");
CHECK(!OrderedHashSet::HasKey(isolate, *set, *key2));
set = OrderedHashSet::Add(isolate, set, key2);
set = OrderedHashSet::Add(isolate, set, key2).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(2, set->NumberOfElements());
......@@ -961,7 +961,7 @@ TEST(OrderedHashSetDeletion) {
Handle<Symbol> key3 = factory->NewSymbol();
CHECK(!OrderedHashSet::HasKey(isolate, *set, *key3));
set = OrderedHashSet::Add(isolate, set, key3);
set = OrderedHashSet::Add(isolate, set, key3).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(3, set->NumberOfElements());
......@@ -1010,7 +1010,7 @@ TEST(OrderedHashSetDeletion) {
// Delete non existent key from non empty hash table
set = OrderedHashSet::Shrink(isolate, set);
set = OrderedHashSet::Add(isolate, set, key1);
set = OrderedHashSet::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
......@@ -1156,7 +1156,7 @@ TEST(OrderedHashSetDuplicateHashCodeDeletion) {
Handle<OrderedHashSet> set = factory->NewOrderedHashSet();
Handle<JSObject> key1 = factory->NewJSObjectWithNullProto();
set = OrderedHashSet::Add(isolate, set, key1);
set = OrderedHashSet::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK_EQ(2, set->NumberOfBuckets());
CHECK_EQ(1, set->NumberOfElements());
......@@ -1209,25 +1209,26 @@ TEST(OrderedHashSetHandlerInsertion) {
Isolate* isolate = GetIsolateFrom(&context);
HandleScope scope(isolate);
Handle<HeapObject> set = OrderedHashSetHandler::Allocate(isolate, 4);
Handle<HeapObject> set =
OrderedHashSetHandler::Allocate(isolate, 4).ToHandleChecked();
Verify(isolate, set);
// Add a new key.
Handle<Smi> key1(Smi::FromInt(1), isolate);
CHECK(!OrderedHashSetHandler::HasKey(isolate, set, key1));
set = OrderedHashSetHandler::Add(isolate, set, key1);
set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1));
// Add existing key.
set = OrderedHashSetHandler::Add(isolate, set, key1);
set = OrderedHashSetHandler::Add(isolate, set, key1).ToHandleChecked();
Verify(isolate, set);
CHECK(OrderedHashSetHandler::HasKey(isolate, set, key1));
CHECK(SmallOrderedHashSet::Is(set));
for (int i = 0; i < 1024; i++) {
Handle<Smi> key_i(Smi::FromInt(i), isolate);
set = OrderedHashSetHandler::Add(isolate, set, key_i);
set = OrderedHashSetHandler::Add(isolate, set, key_i).ToHandleChecked();
Verify(isolate, set);
for (int j = 0; j <= i; j++) {
Handle<Smi> key_j(Smi::FromInt(j), isolate);
......@@ -1242,26 +1243,30 @@ TEST(OrderedHashMapHandlerInsertion) {
Isolate* isolate = GetIsolateFrom(&context);
HandleScope scope(isolate);
Handle<HeapObject> map = OrderedHashMapHandler::Allocate(isolate, 4);
Handle<HeapObject> map =
OrderedHashMapHandler::Allocate(isolate, 4).ToHandleChecked();
Verify(isolate, map);
// Add a new key.
Handle<Smi> key1(Smi::FromInt(1), isolate);
Handle<Smi> value1(Smi::FromInt(1), isolate);
CHECK(!OrderedHashMapHandler::HasKey(isolate, map, key1));
map = OrderedHashMapHandler::Add(isolate, map, key1, value1);
map =
OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1));
// Add existing key.
map = OrderedHashMapHandler::Add(isolate, map, key1, value1);
map =
OrderedHashMapHandler::Add(isolate, map, key1, value1).ToHandleChecked();
Verify(isolate, map);
CHECK(OrderedHashMapHandler::HasKey(isolate, map, key1));
CHECK(SmallOrderedHashMap::Is(map));
for (int i = 0; i < 1024; i++) {
Handle<Smi> key_i(Smi::FromInt(i), isolate);
Handle<Smi> value_i(Smi::FromInt(i), isolate);
map = OrderedHashMapHandler::Add(isolate, map, key_i, value_i);
map = OrderedHashMapHandler::Add(isolate, map, key_i, value_i)
.ToHandleChecked();
Verify(isolate, map);
for (int j = 0; j <= i; j++) {
Handle<Smi> key_j(Smi::FromInt(j), isolate);
......@@ -1286,7 +1291,8 @@ TEST(OrderedNameDictionaryInsertion) {
Handle<String> value = isolate->factory()->InternalizeUtf8String("bar");
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key1));
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1295,7 +1301,8 @@ TEST(OrderedNameDictionaryInsertion) {
Handle<Symbol> key2 = factory->NewSymbol();
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key2));
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(2, dict->NumberOfElements());
......@@ -1317,7 +1324,8 @@ TEST(OrderedNameDictionaryFindEntry) {
Handle<String> key1 = isolate->factory()->InternalizeUtf8String("foo");
Handle<String> value = isolate->factory()->InternalizeUtf8String("bar");
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1327,7 +1335,8 @@ TEST(OrderedNameDictionaryFindEntry) {
CHECK_NE(entry, OrderedNameDictionary::kNotFound);
Handle<Symbol> key2 = factory->NewSymbol();
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(2, dict->NumberOfElements());
......@@ -1356,7 +1365,8 @@ TEST(OrderedNameDictionaryValueAtAndValueAtPut) {
Handle<String> value = isolate->factory()->InternalizeUtf8String("bar");
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key1));
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1376,7 +1386,8 @@ TEST(OrderedNameDictionaryValueAtAndValueAtPut) {
Handle<Symbol> key2 = factory->NewSymbol();
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key2));
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(2, dict->NumberOfElements());
......@@ -1414,7 +1425,8 @@ TEST(OrderedNameDictionaryDetailsAtAndDetailsAtPut) {
Handle<String> value = isolate->factory()->InternalizeUtf8String("bar");
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key1));
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key1, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1434,7 +1446,8 @@ TEST(OrderedNameDictionaryDetailsAtAndDetailsAtPut) {
Handle<Symbol> key2 = factory->NewSymbol();
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key2));
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key2, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(2, dict->NumberOfElements());
......@@ -1725,7 +1738,8 @@ TEST(OrderedNameDictionarySetAndMigrateHash) {
for (int i = 0; i <= 1024; i++) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", i));
Handle<String> key = isolate->factory()->InternalizeUtf8String(buf);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(100, dict->Hash());
}
......@@ -1736,7 +1750,8 @@ TEST(OrderedNameDictionaryHandlerInsertion) {
Isolate* isolate = GetIsolateFrom(&context);
HandleScope scope(isolate);
Handle<HeapObject> table = OrderedNameDictionaryHandler::Allocate(isolate, 4);
Handle<HeapObject> table =
OrderedNameDictionaryHandler::Allocate(isolate, 4).ToHandleChecked();
CHECK(table->IsSmallOrderedNameDictionary());
Verify(isolate, table);
......@@ -1745,8 +1760,8 @@ TEST(OrderedNameDictionaryHandlerInsertion) {
Handle<String> key = isolate->factory()->InternalizeUtf8String("foo");
PropertyDetails details = PropertyDetails::Empty();
table =
OrderedNameDictionaryHandler::Add(isolate, table, key, value, details);
table = OrderedNameDictionaryHandler::Add(isolate, table, key, value, details)
.ToHandleChecked();
DCHECK(key->IsUniqueName());
Verify(isolate, table);
CHECK(table->IsSmallOrderedNameDictionary());
......@@ -1758,7 +1773,8 @@ TEST(OrderedNameDictionaryHandlerInsertion) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", i));
key = isolate->factory()->InternalizeUtf8String(buf);
table =
OrderedNameDictionaryHandler::Add(isolate, table, key, value, details);
OrderedNameDictionaryHandler::Add(isolate, table, key, value, details)
.ToHandleChecked();
DCHECK(key->IsUniqueName());
Verify(isolate, table);
......@@ -1798,7 +1814,8 @@ TEST(OrderedNameDictionarySetEntry) {
Handle<String> value = factory->InternalizeUtf8String("bar");
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key));
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1884,7 +1901,8 @@ TEST(OrderedNameDictionaryDeleteEntry) {
Handle<String> value = factory->InternalizeUtf8String("bar");
CHECK_EQ(OrderedNameDictionary::kNotFound, dict->FindEntry(isolate, *key));
PropertyDetails details = PropertyDetails::Empty();
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details)
.ToHandleChecked();
Verify(isolate, dict);
CHECK_EQ(2, dict->NumberOfBuckets());
CHECK_EQ(1, dict->NumberOfElements());
......@@ -1903,7 +1921,8 @@ TEST(OrderedNameDictionaryDeleteEntry) {
for (int i = 0; i < 100; i++) {
CHECK_LT(0, snprintf(buf, sizeof(buf), "foo%d", i));
key = factory->InternalizeUtf8String(buf);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details);
dict = OrderedNameDictionary::Add(isolate, dict, key, value, details)
.ToHandleChecked();
DCHECK(key->IsUniqueName());
Verify(isolate, dict);
}
......
......@@ -182,6 +182,7 @@
'regress/regress-605470': [PASS, SLOW],
'regress/regress-655573': [PASS, SLOW],
'regress/regress-1200351': [PASS, SLOW],
'regress/regress-crbug-918301': [PASS, SLOW, NO_VARIANTS, ['mode != release or dcheck_always_on', SKIP], ['(arch == arm or arch == arm64) and simulator_run', SKIP], ['tsan', SKIP]],
'regress/wasm/regress-810973': [PASS, SLOW],
'string-replace-gc': [PASS, SLOW],
'wasm/asm-wasm-f32': [PASS, SLOW],
......
// Copyright 2019 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
assertThrows(() => Object.getOwnPropertyDescriptors(Array(1e9).join('c')), RangeError);
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment