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