Revert "[builtins] Port Map and Set iterators to CodeStubAssembler."

This reverts commit 3f22832be7.

Reason for revert: Layout tests:
https://build.chromium.org/p/client.v8.fyi/builders/V8-Blink%20Linux%2064/builds/16849

Original change's description:
> [builtins] Port Map and Set iterators to CodeStubAssembler.
> 
> This is the next step towards faster Map and Set iteration. It
> introduces the appropriate instance types for Map and Set
> iterators (following the pattern for Array iterators) and migrates
> the following builtins to the CodeStubAssembler:
> 
>   - Set.prototype.entries
>   - Set.prototype.values
>   - Map.prototype.entries
>   - Map.prototype.keys
>   - Map.prototype.values
>   - %SetIteratorPrototype%.next
>   - %MapIteratorPrototype%.next
> 
> This already provides a significant performance boost for regular
> for-of iteration of Sets and Maps, by a factor of 5-10 depending
> on the input. The final step will be to inline some fast-paths
> into TurboFan.
> 
> Drive-by-fix: Remove obsolete %IsJSSetIterator and %IsJSMapIterator
> intrinsics and runtime functions.
> 
> Bug: v8:6571, chromium:740122
> Change-Id: Iad7a7dec643d8f8b5799327f89a351108ae856bf
> Reviewed-on: https://chromium-review.googlesource.com/563399
> Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
> Reviewed-by: Jakob Gruber <jgruber@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#46492}

TBR=jgruber@chromium.org,bmeurer@chromium.org

# Not skipping CQ checks because original CL landed > 1 day ago.

Bug: v8:6571, chromium:740122
Change-Id: Iadb48d72e3b85ec8ad880e50ab7912c5502caf07
Reviewed-on: https://chromium-review.googlesource.com/564419
Reviewed-by: Michael Achenbach <machenbach@chromium.org>
Reviewed-by: Benedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Benedikt Meurer <bmeurer@chromium.org>
Cr-Commit-Position: refs/heads/master@{#46495}
This commit is contained in:
Michael Achenbach 2017-07-09 21:21:19 +00:00 committed by Commit Bot
parent cf8d672d96
commit 5a6e24e9e4
30 changed files with 316 additions and 625 deletions

View File

@ -7378,20 +7378,13 @@ Maybe<bool> Map::Delete(Local<Context> context, Local<Value> key) {
}
namespace {
enum class MapAsArrayKind {
kEntries = i::JS_MAP_KEY_VALUE_ITERATOR_TYPE,
kKeys = i::JS_MAP_KEY_ITERATOR_TYPE,
kValues = i::JS_MAP_VALUE_ITERATOR_TYPE
};
i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
int offset, MapAsArrayKind kind) {
int offset, int kind) {
i::Factory* factory = isolate->factory();
i::Handle<i::OrderedHashMap> table(i::OrderedHashMap::cast(table_obj));
if (offset >= table->NumberOfElements()) return factory->NewJSArray(0);
int length = (table->NumberOfElements() - offset) *
(kind == MapAsArrayKind::kEntries ? 2 : 1);
(kind == i::JSMapIterator::kKindEntries ? 2 : 1);
i::Handle<i::FixedArray> result = factory->NewFixedArray(length);
int result_index = 0;
{
@ -7402,10 +7395,12 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
i::Object* key = table->KeyAt(i);
if (key == the_hole) continue;
if (offset-- > 0) continue;
if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kKeys) {
if (kind == i::JSMapIterator::kKindEntries ||
kind == i::JSMapIterator::kKindKeys) {
result->set(result_index++, key);
}
if (kind == MapAsArrayKind::kEntries || kind == MapAsArrayKind::kValues) {
if (kind == i::JSMapIterator::kKindEntries ||
kind == i::JSMapIterator::kKindValues) {
result->set(result_index++, table->ValueAt(i));
}
}
@ -7414,7 +7409,6 @@ i::Handle<i::JSArray> MapAsArray(i::Isolate* isolate, i::Object* table_obj,
DCHECK_EQ(result_index, length);
return factory->NewJSArrayWithElements(result, i::PACKED_ELEMENTS, length);
}
} // namespace
Local<Array> Map::AsArray() const {
@ -7423,7 +7417,7 @@ Local<Array> Map::AsArray() const {
LOG_API(isolate, Map, AsArray);
ENTER_V8_NO_SCRIPT_NO_EXCEPTION(isolate);
return Utils::ToLocal(
MapAsArray(isolate, obj->table(), 0, MapAsArrayKind::kEntries));
MapAsArray(isolate, obj->table(), 0, i::JSMapIterator::kKindEntries));
}
@ -9783,13 +9777,12 @@ v8::MaybeLocal<v8::Array> debug::EntriesPreview(Isolate* v8_isolate,
if (object->IsJSMapIterator()) {
i::Handle<i::JSMapIterator> iterator =
i::Handle<i::JSMapIterator>::cast(object);
MapAsArrayKind const kind =
static_cast<MapAsArrayKind>(iterator->map()->instance_type());
*is_key_value = kind == MapAsArrayKind::kEntries;
int iterator_kind = i::Smi::cast(iterator->kind())->value();
*is_key_value = iterator_kind == i::JSMapIterator::kKindEntries;
if (!iterator->HasMore()) return v8::Array::New(v8_isolate);
return Utils::ToLocal(MapAsArray(isolate, iterator->table(),
i::Smi::cast(iterator->index())->value(),
kind));
iterator_kind));
}
if (object->IsJSSetIterator()) {
i::Handle<i::JSSetIterator> it = i::Handle<i::JSSetIterator>::cast(object);

View File

@ -3643,20 +3643,10 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
// Setup SetIterator constructor.
Handle<JSFunction> set_iterator_function =
InstallFunction(container, "SetIterator", JS_SET_VALUE_ITERATOR_TYPE,
InstallFunction(container, "SetIterator", JS_SET_ITERATOR_TYPE,
JSSetIterator::kSize, prototype, Builtins::kIllegal);
set_iterator_function->shared()->set_native(false);
set_iterator_function->shared()->set_instance_class_name(*name);
Handle<Map> set_value_iterator_map(set_iterator_function->initial_map(),
isolate);
native_context->set_set_value_iterator_map(*set_value_iterator_map);
Handle<Map> set_key_value_iterator_map =
Map::Copy(set_value_iterator_map, "JS_SET_KEY_VALUE_ITERATOR_TYPE");
set_key_value_iterator_map->set_instance_type(
JS_SET_KEY_VALUE_ITERATOR_TYPE);
native_context->set_set_key_value_iterator_map(*set_key_value_iterator_map);
native_context->set_set_iterator_map(set_iterator_function->initial_map());
}
{ // -- M a p I t e r a t o r
@ -3679,25 +3669,10 @@ void Bootstrapper::ExportFromRuntime(Isolate* isolate,
// Setup MapIterator constructor.
Handle<JSFunction> map_iterator_function =
InstallFunction(container, "MapIterator", JS_MAP_KEY_ITERATOR_TYPE,
InstallFunction(container, "MapIterator", JS_MAP_ITERATOR_TYPE,
JSMapIterator::kSize, prototype, Builtins::kIllegal);
map_iterator_function->shared()->set_native(false);
map_iterator_function->shared()->set_instance_class_name(*name);
Handle<Map> map_key_iterator_map(map_iterator_function->initial_map(),
isolate);
native_context->set_map_key_iterator_map(*map_key_iterator_map);
Handle<Map> map_key_value_iterator_map =
Map::Copy(map_key_iterator_map, "JS_MAP_KEY_VALUE_ITERATOR_TYPE");
map_key_value_iterator_map->set_instance_type(
JS_MAP_KEY_VALUE_ITERATOR_TYPE);
native_context->set_map_key_value_iterator_map(*map_key_value_iterator_map);
Handle<Map> map_value_iterator_map =
Map::Copy(map_key_iterator_map, "JS_MAP_VALUE_ITERATOR_TYPE");
map_value_iterator_map->set_instance_type(JS_MAP_VALUE_ITERATOR_TYPE);
native_context->set_map_value_iterator_map(*map_value_iterator_map);
native_context->set_map_iterator_map(map_iterator_function->initial_map());
}
{ // -- S c r i p t

View File

@ -24,20 +24,11 @@ class CollectionsBuiltinsAssembler : public CodeStubAssembler {
template <typename CollectionType>
Node* AllocateOrderedHashTable();
Node* AllocateJSCollection(Node* js_map_function);
template <typename IteratorType>
Node* AllocateJSCollectionIterator(Node* context, int map_index,
Node* collection);
Node* CallGetRaw(Node* const table, Node* const key);
template <typename CollectionType, int entrysize>
Node* CallHasRaw(Node* const table, Node* const key);
template <typename IteratorType, typename TableType>
std::tuple<Node*, Node*> Transition(Node* const iterator);
template <typename TableType>
std::tuple<Node*, Node*, Node*> NextSkipHoles(Node* table, Node* index,
Label* if_end);
// Builds code that finds OrderedHashMap entry for given key with hash code
// {hash} with using the comparison code generated by {key_compare}. The code
// jumps to {entry_found} if the key is found, or to {not_found} if the key
@ -136,24 +127,6 @@ Node* CollectionsBuiltinsAssembler::AllocateJSCollection(
return instance;
}
template <typename IteratorType>
Node* CollectionsBuiltinsAssembler::AllocateJSCollectionIterator(
Node* context, int map_index, Node* collection) {
Node* const table = LoadObjectField(collection, JSCollection::kTableOffset);
Node* const native_context = LoadNativeContext(context);
Node* const iterator_map = LoadContextElement(native_context, map_index);
Node* const iterator = AllocateInNewSpace(IteratorType::kSize);
StoreMapNoWriteBarrier(iterator, iterator_map);
StoreObjectFieldRoot(iterator, IteratorType::kPropertiesOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldRoot(iterator, IteratorType::kElementsOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldNoWriteBarrier(iterator, IteratorType::kTableOffset, table);
StoreObjectFieldNoWriteBarrier(iterator, IteratorType::kIndexOffset,
SmiConstant(0));
return iterator;
}
TF_BUILTIN(MapConstructor, CollectionsBuiltinsAssembler) {
const int kIterableArg = 0;
@ -574,115 +547,6 @@ void CollectionsBuiltinsAssembler::FindOrderedHashMapEntry(
}
}
template <typename IteratorType, typename TableType>
std::tuple<Node*, Node*> CollectionsBuiltinsAssembler::Transition(
Node* const iterator) {
VARIABLE(var_table, MachineRepresentation::kTagged,
LoadObjectField(iterator, IteratorType::kTableOffset));
VARIABLE(var_index, MachineType::PointerRepresentation(),
LoadAndUntagObjectField(iterator, IteratorType::kIndexOffset));
Label if_done(this), if_transition(this, Label::kDeferred);
Branch(TaggedIsSmi(
LoadObjectField(var_table.value(), TableType::kNextTableOffset)),
&if_done, &if_transition);
BIND(&if_transition);
{
Label loop(this, {&var_table, &var_index}), done_loop(this);
Goto(&loop);
BIND(&loop);
{
Node* next_table =
LoadObjectField(var_table.value(), TableType::kNextTableOffset);
GotoIf(TaggedIsSmi(next_table), &done_loop);
Node* table = var_table.value();
Node* index = var_index.value();
var_table.Bind(next_table);
// Check if we need to update the {index}.
GotoIfNot(IntPtrLessThan(IntPtrConstant(0), index), &loop);
// Check if the {table} was cleared.
Node* nod = LoadAndUntagObjectField(
table, TableType::kNumberOfDeletedElementsOffset);
Label if_table_cleared(this), if_table_not_cleared(this);
Branch(WordEqual(nod, IntPtrConstant(TableType::kClearedTableSentinel)),
&if_table_cleared, &if_table_not_cleared);
BIND(&if_table_cleared);
{
var_index.Bind(IntPtrConstant(0));
Goto(&loop);
}
BIND(&if_table_not_cleared);
{
VARIABLE(var_i, MachineType::PointerRepresentation(),
IntPtrConstant(0));
Label iloop(this, {&var_i, &var_index});
Goto(&iloop);
BIND(&iloop);
{
Node* i = var_i.value();
GotoIfNot(IntPtrLessThan(i, nod), &loop);
Node* removed_index = SmiUntag(
LoadFixedArrayElement(table, i, TableType::kRemovedHolesOffset));
GotoIf(IntPtrLessThanOrEqual(index, removed_index), &loop);
var_index.Bind(IntPtrSub(var_index.value(), IntPtrConstant(1)));
Goto(&iloop);
}
}
}
BIND(&done_loop);
// Update the {iterator} with the new state.
StoreObjectField(iterator, IteratorType::kTableOffset, var_table.value());
StoreObjectFieldNoWriteBarrier(iterator, IteratorType::kIndexOffset,
SmiTag(var_index.value()));
Goto(&if_done);
}
BIND(&if_done);
return std::tuple<Node*, Node*>(var_table.value(), var_index.value());
}
template <typename TableType>
std::tuple<Node*, Node*, Node*> CollectionsBuiltinsAssembler::NextSkipHoles(
Node* table, Node* index, Label* if_end) {
// Compute the used capacity for the {table}.
Node* number_of_buckets =
SmiUntag(LoadFixedArrayElement(table, TableType::kNumberOfBucketsIndex));
Node* number_of_elements =
LoadAndUntagObjectField(table, TableType::kNumberOfElementsOffset);
Node* number_of_deleted_elements =
LoadAndUntagObjectField(table, TableType::kNumberOfDeletedElementsOffset);
Node* used_capacity =
IntPtrAdd(number_of_elements, number_of_deleted_elements);
Node* entry_key;
Node* entry_start_position;
VARIABLE(var_index, MachineType::PointerRepresentation(), index);
Label loop(this, &var_index), done_loop(this);
Goto(&loop);
BIND(&loop);
{
GotoIfNot(IntPtrLessThan(var_index.value(), used_capacity), if_end);
entry_start_position = IntPtrAdd(
IntPtrMul(var_index.value(), IntPtrConstant(TableType::kEntrySize)),
number_of_buckets);
entry_key =
LoadFixedArrayElement(table, entry_start_position,
TableType::kHashTableStartIndex * kPointerSize);
Increment(var_index);
Branch(IsTheHole(entry_key), &loop, &done_loop);
}
BIND(&done_loop);
return std::tuple<Node*, Node*, Node*>(entry_key, entry_start_position,
var_index.value());
}
TF_BUILTIN(MapGet, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const key_tagged = Parameter(Descriptor::kKey);
@ -754,110 +618,6 @@ TF_BUILTIN(MapHas, CollectionsBuiltinsAssembler) {
Return(FalseConstant());
}
TF_BUILTIN(MapPrototypeEntries, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE,
"Map.prototype.entries");
Return(AllocateJSCollectionIterator<JSMapIterator>(
context, Context::MAP_KEY_VALUE_ITERATOR_MAP_INDEX, receiver));
}
TF_BUILTIN(MapPrototypeKeys, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE, "Map.prototype.keys");
Return(AllocateJSCollectionIterator<JSMapIterator>(
context, Context::MAP_KEY_ITERATOR_MAP_INDEX, receiver));
}
TF_BUILTIN(MapPrototypeValues, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_MAP_TYPE,
"Map.prototype.values");
Return(AllocateJSCollectionIterator<JSMapIterator>(
context, Context::MAP_VALUE_ITERATOR_MAP_INDEX, receiver));
}
TF_BUILTIN(MapIteratorPrototypeNext, CollectionsBuiltinsAssembler) {
const char* const kMethodName = "Map Iterator.prototype.next";
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
// Ensure that the {receiver} is actually a JSMapIterator.
Label if_receiver_valid(this), if_receiver_invalid(this, Label::kDeferred);
GotoIf(TaggedIsSmi(receiver), &if_receiver_invalid);
Node* const receiver_instance_type = LoadInstanceType(receiver);
GotoIf(
InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_VALUE_ITERATOR_TYPE),
&if_receiver_valid);
GotoIf(InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_ITERATOR_TYPE),
&if_receiver_valid);
Branch(InstanceTypeEqual(receiver_instance_type, JS_MAP_VALUE_ITERATOR_TYPE),
&if_receiver_valid, &if_receiver_invalid);
BIND(&if_receiver_invalid);
ThrowIncompatibleMethodReceiver(context, kMethodName, receiver);
BIND(&if_receiver_valid);
// Check if the {receiver} is exhausted.
Label return_value(this), return_entry(this),
return_end(this, Label::kDeferred);
VARIABLE(var_value, MachineRepresentation::kTagged, UndefinedConstant());
VARIABLE(var_done, MachineRepresentation::kTagged, TrueConstant());
// TODO(bmeurer): Don't stick undefined in here, but some canonical
// empty_table, to avoid this check.
GotoIf(IsUndefined(LoadObjectField(receiver, JSMapIterator::kTableOffset)),
&return_value);
// Transition the {receiver} table if necessary.
Node* table;
Node* index;
std::tie(table, index) = Transition<JSMapIterator, OrderedHashMap>(receiver);
// Read the next entry from the {table}, skipping holes.
Node* entry_key;
Node* entry_start_position;
std::tie(entry_key, entry_start_position, index) =
NextSkipHoles<OrderedHashMap>(table, index, &return_end);
StoreObjectFieldNoWriteBarrier(receiver, JSMapIterator::kIndexOffset,
SmiTag(index));
var_value.Bind(entry_key);
var_done.Bind(FalseConstant());
// Check how to return the {key} (depending on {receiver} type).
GotoIf(InstanceTypeEqual(receiver_instance_type, JS_MAP_KEY_ITERATOR_TYPE),
&return_value);
var_value.Bind(LoadFixedArrayElement(
table, entry_start_position,
(OrderedHashMap::kHashTableStartIndex + OrderedHashMap::kValueOffset) *
kPointerSize));
Branch(InstanceTypeEqual(receiver_instance_type, JS_MAP_VALUE_ITERATOR_TYPE),
&return_value, &return_entry);
BIND(&return_entry);
{
Node* result =
AllocateJSIteratorResultForEntry(context, entry_key, var_value.value());
Return(result);
}
BIND(&return_value);
{
Node* result =
AllocateJSIteratorResult(context, var_value.value(), var_done.value());
Return(result);
}
BIND(&return_end);
{
StoreObjectFieldRoot(receiver, JSMapIterator::kTableOffset,
Heap::kUndefinedValueRootIndex);
var_value.Bind(UndefinedConstant());
Goto(&return_value);
}
}
TF_BUILTIN(SetHas, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const key = Parameter(Descriptor::kKey);
@ -869,93 +629,5 @@ TF_BUILTIN(SetHas, CollectionsBuiltinsAssembler) {
Return(CallHasRaw<OrderedHashSet, 1>(table, key));
}
TF_BUILTIN(SetPrototypeEntries, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE,
"Set.prototype.entries");
Return(AllocateJSCollectionIterator<JSSetIterator>(
context, Context::SET_KEY_VALUE_ITERATOR_MAP_INDEX, receiver));
}
TF_BUILTIN(SetPrototypeValues, CollectionsBuiltinsAssembler) {
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
ThrowIfNotInstanceType(context, receiver, JS_SET_TYPE,
"Set.prototype.values");
Return(AllocateJSCollectionIterator<JSSetIterator>(
context, Context::SET_VALUE_ITERATOR_MAP_INDEX, receiver));
}
TF_BUILTIN(SetIteratorPrototypeNext, CollectionsBuiltinsAssembler) {
const char* const kMethodName = "Set Iterator.prototype.next";
Node* const receiver = Parameter(Descriptor::kReceiver);
Node* const context = Parameter(Descriptor::kContext);
// Ensure that the {receiver} is actually a JSSetIterator.
Label if_receiver_valid(this), if_receiver_invalid(this, Label::kDeferred);
GotoIf(TaggedIsSmi(receiver), &if_receiver_invalid);
Node* const receiver_instance_type = LoadInstanceType(receiver);
GotoIf(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE),
&if_receiver_valid);
Branch(
InstanceTypeEqual(receiver_instance_type, JS_SET_KEY_VALUE_ITERATOR_TYPE),
&if_receiver_valid, &if_receiver_invalid);
BIND(&if_receiver_invalid);
ThrowIncompatibleMethodReceiver(context, kMethodName, receiver);
BIND(&if_receiver_valid);
// Check if the {receiver} is exhausted.
Label return_value(this), return_entry(this),
return_end(this, Label::kDeferred);
VARIABLE(var_value, MachineRepresentation::kTagged, UndefinedConstant());
VARIABLE(var_done, MachineRepresentation::kTagged, TrueConstant());
// TODO(bmeurer): Don't stick undefined in here, but some canonical
// empty_table, to avoid this check.
GotoIf(IsUndefined(LoadObjectField(receiver, JSSetIterator::kTableOffset)),
&return_value);
// Transition the {receiver} table if necessary.
Node* table;
Node* index;
std::tie(table, index) = Transition<JSSetIterator, OrderedHashSet>(receiver);
// Read the next entry from the {table}, skipping holes.
Node* entry_key;
Node* entry_start_position;
std::tie(entry_key, entry_start_position, index) =
NextSkipHoles<OrderedHashSet>(table, index, &return_end);
StoreObjectFieldNoWriteBarrier(receiver, JSSetIterator::kIndexOffset,
SmiTag(index));
var_value.Bind(entry_key);
var_done.Bind(FalseConstant());
// Check how to return the {key} (depending on {receiver} type).
Branch(InstanceTypeEqual(receiver_instance_type, JS_SET_VALUE_ITERATOR_TYPE),
&return_value, &return_entry);
BIND(&return_entry);
{
Node* result = AllocateJSIteratorResultForEntry(context, var_value.value(),
var_value.value());
Return(result);
}
BIND(&return_value);
{
Node* result =
AllocateJSIteratorResult(context, var_value.value(), var_done.value());
Return(result);
}
BIND(&return_end);
{
StoreObjectFieldRoot(receiver, JSSetIterator::kTableOffset,
Heap::kUndefinedValueRootIndex);
var_value.Bind(UndefinedConstant());
Goto(&return_value);
}
}
} // namespace internal
} // namespace v8

View File

@ -43,7 +43,7 @@ BUILTIN(MapForEach) {
Handle<Object> receiver = args.atOrUndefined(isolate, 2);
Handle<OrderedHashMap> table(OrderedHashMap::cast(map->table()), isolate);
Handle<JSMapIterator> iterator = isolate->factory()->NewJSMapIterator(
isolate->map_key_value_iterator_map(), table, 0);
table, 0, JSMapIterator::kKindEntries);
while (iterator->HasMore()) {
Handle<Object> key(iterator->CurrentKey(), isolate);
@ -58,6 +58,58 @@ BUILTIN(MapForEach) {
return isolate->heap()->undefined_value();
}
BUILTIN(MapPrototypeEntries) {
HandleScope scope(isolate);
const char* const kMethodName = "Map.prototype.entries";
CHECK_RECEIVER(JSMap, map, kMethodName);
return *isolate->factory()->NewJSMapIterator(
handle(OrderedHashMap::cast(map->table()), isolate), 0,
JSMapIterator::kKindEntries);
}
BUILTIN(MapPrototypeKeys) {
HandleScope scope(isolate);
const char* const kMethodName = "Map.prototype.keys";
CHECK_RECEIVER(JSMap, map, kMethodName);
return *isolate->factory()->NewJSMapIterator(
handle(OrderedHashMap::cast(map->table()), isolate), 0,
JSMapIterator::kKindKeys);
}
BUILTIN(MapPrototypeValues) {
HandleScope scope(isolate);
const char* const kMethodName = "Map.prototype.values";
CHECK_RECEIVER(JSMap, map, kMethodName);
return *isolate->factory()->NewJSMapIterator(
handle(OrderedHashMap::cast(map->table()), isolate), 0,
JSMapIterator::kKindValues);
}
BUILTIN(MapIteratorPrototypeNext) {
HandleScope scope(isolate);
const char* const kMethodName = "Map Iterator.prototype.next";
CHECK_RECEIVER(JSMapIterator, iterator, kMethodName);
Handle<Object> value = isolate->factory()->undefined_value();
bool done = true;
if (iterator->HasMore()) {
done = false;
switch (Smi::cast(iterator->kind())->value()) {
case JSMapIterator::kKindEntries:
value = MakeEntryPair(isolate, handle(iterator->CurrentKey(), isolate),
handle(iterator->CurrentValue(), isolate));
break;
case JSMapIterator::kKindKeys:
value = handle(iterator->CurrentKey(), isolate);
break;
case JSMapIterator::kKindValues:
value = handle(iterator->CurrentValue(), isolate);
break;
}
iterator->MoveNext();
}
return *isolate->factory()->NewJSIteratorResult(value, done);
}
BUILTIN(SetGetSize) {
HandleScope scope(isolate);
const char* const kMethodName = "get Set.prototype.size";
@ -92,7 +144,7 @@ BUILTIN(SetForEach) {
Handle<Object> receiver = args.atOrUndefined(isolate, 2);
Handle<OrderedHashSet> table(OrderedHashSet::cast(set->table()), isolate);
Handle<JSSetIterator> iterator = isolate->factory()->NewJSSetIterator(
isolate->set_value_iterator_map(), table, 0);
table, 0, JSSetIterator::kKindValues);
while (iterator->HasMore()) {
Handle<Object> key(iterator->CurrentKey(), isolate);
@ -106,5 +158,40 @@ BUILTIN(SetForEach) {
return isolate->heap()->undefined_value();
}
BUILTIN(SetPrototypeEntries) {
HandleScope scope(isolate);
const char* const kMethodName = "Set.prototype.entries";
CHECK_RECEIVER(JSSet, set, kMethodName);
return *isolate->factory()->NewJSSetIterator(
handle(OrderedHashSet::cast(set->table()), isolate), 0,
JSSetIterator::kKindEntries);
}
BUILTIN(SetPrototypeValues) {
HandleScope scope(isolate);
const char* const kMethodName = "Set.prototype.values";
CHECK_RECEIVER(JSSet, set, kMethodName);
return *isolate->factory()->NewJSSetIterator(
handle(OrderedHashSet::cast(set->table()), isolate), 0,
JSSetIterator::kKindValues);
}
BUILTIN(SetIteratorPrototypeNext) {
HandleScope scope(isolate);
const char* const kMethodName = "Set Iterator.prototype.next";
CHECK_RECEIVER(JSSetIterator, iterator, kMethodName);
Handle<Object> value = isolate->factory()->undefined_value();
bool done = true;
if (iterator->HasMore()) {
value = handle(iterator->CurrentKey(), isolate);
done = false;
if (Smi::cast(iterator->kind())->value() == JSSetIterator::kKindEntries) {
value = MakeEntryPair(isolate, value, value);
}
iterator->MoveNext();
}
return *isolate->factory()->NewJSIteratorResult(value, done);
}
} // namespace internal
} // namespace v8

View File

@ -584,13 +584,13 @@ namespace internal {
CPP(MapClear) \
CPP(MapForEach) \
/* ES #sec-map.prototype.entries */ \
TFJ(MapPrototypeEntries, 0) \
CPP(MapPrototypeEntries) \
/* ES #sec-map.prototype.keys */ \
TFJ(MapPrototypeKeys, 0) \
CPP(MapPrototypeKeys) \
/* ES #sec-map.prototype.values */ \
TFJ(MapPrototypeValues, 0) \
CPP(MapPrototypeValues) \
/* ES #sec-%mapiteratorprototype%.next */ \
TFJ(MapIteratorPrototypeNext, 0) \
CPP(MapIteratorPrototypeNext) \
\
/* Math */ \
/* ES6 #sec-math.abs */ \
@ -874,11 +874,11 @@ namespace internal {
CPP(SetClear) \
CPP(SetForEach) \
/* ES #sec-set.prototype.entries */ \
TFJ(SetPrototypeEntries, 0) \
CPP(SetPrototypeEntries) \
/* ES #sec-set.prototype.values */ \
TFJ(SetPrototypeValues, 0) \
CPP(SetPrototypeValues) \
/* ES #sec-%setiteratorprototype%.next */ \
TFJ(SetIteratorPrototypeNext, 0) \
CPP(SetIteratorPrototypeNext) \
\
/* SharedArrayBuffer */ \
CPP(SharedArrayBufferPrototypeGetByteLength) \

View File

@ -1822,8 +1822,19 @@ TF_BUILTIN(StringIteratorPrototypeNext, StringBuiltinsAssembler) {
BIND(&return_result);
{
Node* result =
AllocateJSIteratorResult(context, var_value.value(), var_done.value());
Node* native_context = LoadNativeContext(context);
Node* map =
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
Node* result = Allocate(JSIteratorResult::kSize);
StoreMapNoWriteBarrier(result, map);
StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset,
var_value.value());
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset,
var_done.value());
Return(result);
}

View File

@ -3138,14 +3138,6 @@ Node* CodeStubAssembler::ToThisValue(Node* context, Node* value,
return var_value.value();
}
void CodeStubAssembler::ThrowIncompatibleMethodReceiver(Node* context,
const char* method_name,
Node* receiver) {
CallRuntime(Runtime::kThrowIncompatibleMethodReceiver, context,
CStringConstant(method_name), receiver);
Unreachable();
}
Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
InstanceType instance_type,
char const* method_name) {
@ -3163,7 +3155,11 @@ Node* CodeStubAssembler::ThrowIfNotInstanceType(Node* context, Node* value,
// The {value} is not a compatible receiver for this method.
BIND(&throw_exception);
ThrowIncompatibleMethodReceiver(context, method_name, value);
CallRuntime(
Runtime::kThrowIncompatibleMethodReceiver, context,
HeapConstant(factory()->NewStringFromAsciiChecked(method_name, TENURED)),
value);
Unreachable();
BIND(&out);
return var_value_map.value();
@ -9156,58 +9152,6 @@ Node* CodeStubAssembler::AllocateJSArrayIterator(Node* array, Node* array_map,
return iterator;
}
Node* CodeStubAssembler::AllocateJSIteratorResult(Node* context, Node* value,
Node* done) {
CSA_ASSERT(this, IsBoolean(done));
Node* native_context = LoadNativeContext(context);
Node* map =
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
Node* result = Allocate(JSIteratorResult::kSize);
StoreMapNoWriteBarrier(result, map);
StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, value);
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kDoneOffset, done);
return result;
}
Node* CodeStubAssembler::AllocateJSIteratorResultForEntry(Node* context,
Node* key,
Node* value) {
Node* native_context = LoadNativeContext(context);
Node* length = SmiConstant(2);
int const elements_size = FixedArray::SizeFor(2);
Node* elements =
Allocate(elements_size + JSArray::kSize + JSIteratorResult::kSize);
StoreObjectFieldRoot(elements, FixedArray::kMapOffset,
Heap::kFixedArrayMapRootIndex);
StoreObjectFieldNoWriteBarrier(elements, FixedArray::kLengthOffset, length);
StoreFixedArrayElement(elements, 0, key);
StoreFixedArrayElement(elements, 1, value);
Node* array_map = LoadContextElement(
native_context, Context::JS_ARRAY_PACKED_ELEMENTS_MAP_INDEX);
Node* array = InnerAllocate(elements, elements_size);
StoreMapNoWriteBarrier(array, array_map);
StoreObjectFieldRoot(array, JSArray::kPropertiesOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldNoWriteBarrier(array, JSArray::kElementsOffset, elements);
StoreObjectFieldNoWriteBarrier(array, JSArray::kLengthOffset, length);
Node* iterator_map =
LoadContextElement(native_context, Context::ITERATOR_RESULT_MAP_INDEX);
Node* result = InnerAllocate(array, JSArray::kSize);
StoreMapNoWriteBarrier(result, iterator_map);
StoreObjectFieldRoot(result, JSIteratorResult::kPropertiesOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldRoot(result, JSIteratorResult::kElementsOffset,
Heap::kEmptyFixedArrayRootIndex);
StoreObjectFieldNoWriteBarrier(result, JSIteratorResult::kValueOffset, array);
StoreObjectFieldRoot(result, JSIteratorResult::kDoneOffset,
Heap::kFalseValueRootIndex);
return result;
}
Node* CodeStubAssembler::TypedArraySpeciesCreateByLength(Node* context,
Node* originalArray,
Node* len) {

View File

@ -648,8 +648,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* context, IterationKind mode);
Node* AllocateJSArrayIterator(Node* array, Node* array_map, Node* map);
Node* AllocateJSIteratorResult(Node* context, Node* value, Node* done);
Node* AllocateJSIteratorResultForEntry(Node* context, Node* key, Node* value);
Node* TypedArraySpeciesCreateByLength(Node* context, Node* originalArray,
Node* len);
@ -758,10 +756,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler {
Node* ToThisValue(Node* context, Node* value, PrimitiveType primitive_type,
char const* method_name);
// Throws a TypeError for {method_name}. Terminates the current block.
void ThrowIncompatibleMethodReceiver(Node* context, char const* method_name,
Node* receiver);
// Throws a TypeError for {method_name} if {value} is not of the given
// instance type. Returns {value}'s map.
Node* ThrowIfNotInstanceType(Node* context, Node* value,

View File

@ -62,6 +62,10 @@ Reduction JSIntrinsicLowering::Reduce(Node* node) {
return ReduceIsInstanceType(node, JS_MAP_TYPE);
case Runtime::kInlineIsJSSet:
return ReduceIsInstanceType(node, JS_SET_TYPE);
case Runtime::kInlineIsJSMapIterator:
return ReduceIsInstanceType(node, JS_MAP_ITERATOR_TYPE);
case Runtime::kInlineIsJSSetIterator:
return ReduceIsInstanceType(node, JS_SET_ITERATOR_TYPE);
case Runtime::kInlineIsJSWeakMap:
return ReduceIsInstanceType(node, JS_WEAK_MAP_TYPE);
case Runtime::kInlineIsJSWeakSet:

View File

@ -183,6 +183,8 @@ bool Linkage::NeedsFrameStateInput(Runtime::FunctionId function) {
case Runtime::kInlineIsArray:
case Runtime::kInlineIsJSMap:
case Runtime::kInlineIsJSSet:
case Runtime::kInlineIsJSMapIterator:
case Runtime::kInlineIsJSSetIterator:
case Runtime::kInlineIsJSWeakMap:
case Runtime::kInlineIsJSWeakSet:
case Runtime::kInlineIsJSReceiver:

View File

@ -222,11 +222,8 @@ Type::bitset BitsetType::Lub(i::Map* map) {
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_ASYNC_FROM_SYNC_ITERATOR_TYPE:

View File

@ -291,9 +291,7 @@ enum ContextLookupFlags {
V(JS_WEAK_MAP_FUN_INDEX, JSFunction, js_weak_map_fun) \
V(JS_WEAK_SET_FUN_INDEX, JSFunction, js_weak_set_fun) \
V(MAP_CACHE_INDEX, Object, map_cache) \
V(MAP_KEY_ITERATOR_MAP_INDEX, Map, map_key_iterator_map) \
V(MAP_KEY_VALUE_ITERATOR_MAP_INDEX, Map, map_key_value_iterator_map) \
V(MAP_VALUE_ITERATOR_MAP_INDEX, Map, map_value_iterator_map) \
V(MAP_ITERATOR_MAP_INDEX, Map, map_iterator_map) \
V(MATH_RANDOM_INDEX_INDEX, Smi, math_random_index) \
V(MATH_RANDOM_CACHE_INDEX, Object, math_random_cache) \
V(MESSAGE_LISTENERS_INDEX, TemplateList, message_listeners) \
@ -334,8 +332,7 @@ enum ContextLookupFlags {
V(SCRIPT_FUNCTION_INDEX, JSFunction, script_function) \
V(SECURITY_TOKEN_INDEX, Object, security_token) \
V(SELF_WEAK_CELL_INDEX, WeakCell, self_weak_cell) \
V(SET_VALUE_ITERATOR_MAP_INDEX, Map, set_value_iterator_map) \
V(SET_KEY_VALUE_ITERATOR_MAP_INDEX, Map, set_key_value_iterator_map) \
V(SET_ITERATOR_MAP_INDEX, Map, set_iterator_map) \
V(SHARED_ARRAY_BUFFER_FUN_INDEX, JSFunction, shared_array_buffer_fun) \
V(SLOPPY_ARGUMENTS_MAP_INDEX, Map, sloppy_arguments_map) \
V(SLOW_ALIASED_ARGUMENTS_MAP_INDEX, Map, slow_aliased_arguments_map) \

View File

@ -277,6 +277,8 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) {
V(IsJSProxy) \
V(IsJSMap) \
V(IsJSSet) \
V(IsJSMapIterator) \
V(IsJSSetIterator) \
V(IsJSWeakMap) \
V(IsJSWeakSet) \
V(IsRegExp) \

View File

@ -3682,35 +3682,6 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
}
return object;
}
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE: {
Handle<JSSetIterator> object = Handle<JSSetIterator>::cast(
isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
Handle<Object> properties = materializer.FieldAt(value_index);
Handle<Object> elements = materializer.FieldAt(value_index);
Handle<Object> table = materializer.FieldAt(value_index);
Handle<Object> index = materializer.FieldAt(value_index);
object->set_properties(FixedArray::cast(*properties));
object->set_elements(FixedArrayBase::cast(*elements));
object->set_table(*table);
object->set_index(*index);
return object;
}
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE: {
Handle<JSMapIterator> object = Handle<JSMapIterator>::cast(
isolate_->factory()->NewJSObjectFromMap(map, NOT_TENURED));
Handle<Object> properties = materializer.FieldAt(value_index);
Handle<Object> elements = materializer.FieldAt(value_index);
Handle<Object> table = materializer.FieldAt(value_index);
Handle<Object> index = materializer.FieldAt(value_index);
object->set_properties(FixedArray::cast(*properties));
object->set_elements(FixedArrayBase::cast(*elements));
object->set_table(*table);
object->set_index(*index);
return object;
}
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
case JS_FAST_ARRAY_KEY_ITERATOR_TYPE:
case JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE:
@ -3963,6 +3934,8 @@ Handle<Object> TranslatedState::MaterializeCapturedObjectAt(
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_WEAK_MAP_TYPE:
case JS_WEAK_SET_TYPE:
case JS_PROMISE_CAPABILITY_TYPE:

View File

@ -2087,23 +2087,27 @@ Handle<JSSet> Factory::NewJSSet() {
return js_set;
}
Handle<JSMapIterator> Factory::NewJSMapIterator(Handle<Map> map,
Handle<OrderedHashMap> table,
int index) {
Handle<JSMapIterator> Factory::NewJSMapIterator(Handle<OrderedHashMap> table,
int index,
JSMapIterator::Kind kind) {
Handle<Map> map(isolate()->native_context()->map_iterator_map(), isolate());
Handle<JSMapIterator> result =
Handle<JSMapIterator>::cast(NewJSObjectFromMap(map));
result->set_table(*table);
result->set_index(Smi::FromInt(index));
result->set_kind(Smi::FromInt(kind));
return result;
}
Handle<JSSetIterator> Factory::NewJSSetIterator(Handle<Map> map,
Handle<OrderedHashSet> table,
int index) {
Handle<JSSetIterator> Factory::NewJSSetIterator(Handle<OrderedHashSet> table,
int index,
JSSetIterator::Kind kind) {
Handle<Map> map(isolate()->native_context()->set_iterator_map(), isolate());
Handle<JSSetIterator> result =
Handle<JSSetIterator>::cast(NewJSObjectFromMap(map));
result->set_table(*table);
result->set_index(Smi::FromInt(index));
result->set_kind(Smi::FromInt(kind));
return result;
}

View File

@ -572,12 +572,10 @@ class V8_EXPORT_PRIVATE Factory final {
Handle<JSMap> NewJSMap();
Handle<JSSet> NewJSSet();
Handle<JSMapIterator> NewJSMapIterator(Handle<Map> map,
Handle<OrderedHashMap> table,
int index);
Handle<JSSetIterator> NewJSSetIterator(Handle<Map> map,
Handle<OrderedHashSet> table,
int index);
Handle<JSMapIterator> NewJSMapIterator(Handle<OrderedHashMap> table,
int index, JSMapIterator::Kind kind);
Handle<JSSetIterator> NewJSSetIterator(Handle<OrderedHashSet> table,
int index, JSSetIterator::Kind kind);
// Allocates a bound function.
MaybeHandle<JSBoundFunction> NewJSBoundFunction(

View File

@ -202,11 +202,21 @@ Node* IntrinsicsGenerator::IsJSMap(Node* input, Node* arg_count,
return IsInstanceType(input, JS_MAP_TYPE);
}
Node* IntrinsicsGenerator::IsJSMapIterator(Node* input, Node* arg_count,
Node* context) {
return IsInstanceType(input, JS_MAP_ITERATOR_TYPE);
}
Node* IntrinsicsGenerator::IsJSSet(Node* input, Node* arg_count,
Node* context) {
return IsInstanceType(input, JS_SET_TYPE);
}
Node* IntrinsicsGenerator::IsJSSetIterator(Node* input, Node* arg_count,
Node* context) {
return IsInstanceType(input, JS_SET_ITERATOR_TYPE);
}
Node* IntrinsicsGenerator::IsJSWeakMap(Node* input, Node* arg_count,
Node* context) {
return IsInstanceType(input, JS_WEAK_MAP_TYPE);

View File

@ -30,9 +30,11 @@ namespace interpreter {
V(HasProperty, has_property, 2) \
V(IsArray, is_array, 1) \
V(IsJSMap, is_js_map, 1) \
V(IsJSMapIterator, is_js_map_iterator, 1) \
V(IsJSProxy, is_js_proxy, 1) \
V(IsJSReceiver, is_js_receiver, 1) \
V(IsJSSet, is_js_set, 1) \
V(IsJSSetIterator, is_js_set_iterator, 1) \
V(IsJSWeakMap, is_js_weak_map, 1) \
V(IsJSWeakSet, is_js_weak_set, 1) \
V(IsSmi, is_smi, 1) \

View File

@ -53,7 +53,7 @@ macro IS_FUNCTION(arg) = (%IsFunction(arg));
macro IS_GENERATOR(arg) = (%_ClassOf(arg) === 'Generator');
macro IS_GLOBAL(arg) = (%_ClassOf(arg) === 'global');
macro IS_MAP(arg) = (%_IsJSMap(arg));
macro IS_MAP_ITERATOR(arg) = (%_ClassOf(arg) === 'Map Iterator');
macro IS_MAP_ITERATOR(arg) = (%_IsJSMapIterator(arg));
macro IS_NULL(arg) = (arg === null);
macro IS_NULL_OR_UNDEFINED(arg) = (arg == null);
macro IS_NUMBER(arg) = (typeof(arg) === 'number');
@ -61,7 +61,7 @@ macro IS_OBJECT(arg) = (typeof(arg) === 'object');
macro IS_PROXY(arg) = (%_IsJSProxy(arg));
macro IS_SCRIPT(arg) = (%_ClassOf(arg) === 'Script');
macro IS_SET(arg) = (%_IsJSSet(arg));
macro IS_SET_ITERATOR(arg) = (%_ClassOf(arg) === 'Set Iterator');
macro IS_SET_ITERATOR(arg) = (%_IsJSSetIterator(arg));
macro IS_SHAREDARRAYBUFFER(arg) = (%_ClassOf(arg) === 'SharedArrayBuffer');
macro IS_STRING(arg) = (typeof(arg) === 'string');
macro IS_SYMBOL(arg) = (typeof(arg) === 'symbol');

View File

@ -611,11 +611,8 @@ ReturnType BodyDescriptorApply(InstanceType type, T1 p1, T2 p2, T3 p3) {
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:

View File

@ -164,13 +164,10 @@ void HeapObject::HeapObjectVerify() {
case JS_MAP_TYPE:
JSMap::cast(this)->JSMapVerify();
break;
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
JSSetIterator::cast(this)->JSSetIteratorVerify();
break;
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
JSMapIterator::cast(this)->JSMapIteratorVerify();
break;
@ -956,7 +953,8 @@ void JSSetIterator::JSSetIteratorVerify() {
VerifyHeapPointer(table());
Isolate* isolate = GetIsolate();
CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
CHECK(index()->IsSmi());
CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
}
@ -966,7 +964,8 @@ void JSMapIterator::JSMapIteratorVerify() {
VerifyHeapPointer(table());
Isolate* isolate = GetIsolate();
CHECK(table()->IsOrderedHashTable() || table()->IsUndefined(isolate));
CHECK(index()->IsSmi());
CHECK(index()->IsSmi() || index()->IsUndefined(isolate));
CHECK(kind()->IsSmi() || kind()->IsUndefined(isolate));
}

View File

@ -92,12 +92,14 @@ TYPE_CHECKER(JSError, JS_ERROR_TYPE)
TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
TYPE_CHECKER(JSMap, JS_MAP_TYPE)
TYPE_CHECKER(JSMapIterator, JS_MAP_ITERATOR_TYPE)
TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
TYPE_CHECKER(JSModuleNamespace, JS_MODULE_NAMESPACE_TYPE)
TYPE_CHECKER(JSPromiseCapability, JS_PROMISE_CAPABILITY_TYPE)
TYPE_CHECKER(JSPromise, JS_PROMISE_TYPE)
TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
TYPE_CHECKER(JSSet, JS_SET_TYPE)
TYPE_CHECKER(JSSetIterator, JS_SET_ITERATOR_TYPE)
TYPE_CHECKER(JSAsyncFromSyncIterator, JS_ASYNC_FROM_SYNC_ITERATOR_TYPE)
TYPE_CHECKER(JSStringIterator, JS_STRING_ITERATOR_TYPE)
TYPE_CHECKER(JSTypedArray, JS_TYPED_ARRAY_TYPE)
@ -287,18 +289,6 @@ bool HeapObject::IsJSObject() const {
bool HeapObject::IsJSProxy() const { return map()->IsJSProxyMap(); }
bool HeapObject::IsJSMapIterator() const {
InstanceType instance_type = map()->instance_type();
return (instance_type >= JS_MAP_KEY_ITERATOR_TYPE &&
instance_type <= JS_MAP_VALUE_ITERATOR_TYPE);
}
bool HeapObject::IsJSSetIterator() const {
InstanceType instance_type = map()->instance_type();
return (instance_type == JS_SET_VALUE_ITERATOR_TYPE ||
instance_type == JS_SET_KEY_VALUE_ITERATOR_TYPE);
}
bool HeapObject::IsJSArrayIterator() const {
InstanceType instance_type = map()->instance_type();
return (instance_type >= FIRST_ARRAY_ITERATOR_TYPE &&
@ -4839,6 +4829,7 @@ ACCESSORS(JSCollection, table, Object, kTableOffset)
ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(table, Object, kTableOffset)
ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(index, Object, kIndexOffset)
ORDERED_HASH_TABLE_ITERATOR_ACCESSORS(kind, Object, kKindOffset)
#undef ORDERED_HASH_TABLE_ITERATOR_ACCESSORS

View File

@ -201,13 +201,10 @@ void HeapObject::HeapObjectPrint(std::ostream& os) { // NOLINT
case JS_MAP_TYPE:
JSMap::cast(this)->JSMapPrint(os);
break;
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
JSSetIterator::cast(this)->JSSetIteratorPrint(os);
break;
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
JSMapIterator::cast(this)->JSMapIteratorPrint(os);
break;
case JS_WEAK_MAP_TYPE:
@ -939,6 +936,7 @@ OrderedHashTableIterator<Derived, TableType>::OrderedHashTableIteratorPrint(
std::ostream& os) { // NOLINT
os << "\n - table = " << Brief(table());
os << "\n - index = " << Brief(index());
os << "\n - kind = " << Brief(kind());
os << "\n";
}

View File

@ -1324,12 +1324,9 @@ int JSObject::GetHeaderSize(InstanceType type) {
return JSSet::kSize;
case JS_MAP_TYPE:
return JSMap::kSize;
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
return JSSetIterator::kSize;
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
return JSMapIterator::kSize;
case JS_WEAK_MAP_TYPE:
return JSWeakMap::kSize;
@ -3048,11 +3045,8 @@ VisitorId Map::GetVisitorId(Map* map) {
case JS_DATA_VIEW_TYPE:
case JS_SET_TYPE:
case JS_MAP_TYPE:
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case JS_MAP_KEY_ITERATOR_TYPE:
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_STRING_ITERATOR_TYPE:
case JS_TYPED_ARRAY_KEY_ITERATOR_TYPE:
@ -12679,6 +12673,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_FUNCTION_TYPE:
case JS_GENERATOR_OBJECT_TYPE:
case JS_ASYNC_GENERATOR_OBJECT_TYPE:
case JS_MAP_ITERATOR_TYPE:
case JS_MAP_TYPE:
case JS_MESSAGE_OBJECT_TYPE:
case JS_OBJECT_TYPE:
@ -12686,6 +12681,7 @@ bool CanSubclassHaveInobjectProperties(InstanceType instance_type) {
case JS_ARGUMENTS_TYPE:
case JS_PROMISE_TYPE:
case JS_REGEXP_TYPE:
case JS_SET_ITERATOR_TYPE:
case JS_SET_TYPE:
case JS_SPECIAL_API_OBJECT_TYPE:
case JS_TYPED_ARRAY_TYPE:

View File

@ -400,11 +400,8 @@ const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
V(JS_DATA_VIEW_TYPE) \
V(JS_SET_TYPE) \
V(JS_MAP_TYPE) \
V(JS_SET_KEY_VALUE_ITERATOR_TYPE) \
V(JS_SET_VALUE_ITERATOR_TYPE) \
V(JS_MAP_KEY_ITERATOR_TYPE) \
V(JS_MAP_KEY_VALUE_ITERATOR_TYPE) \
V(JS_MAP_VALUE_ITERATOR_TYPE) \
V(JS_SET_ITERATOR_TYPE) \
V(JS_MAP_ITERATOR_TYPE) \
V(JS_WEAK_MAP_TYPE) \
V(JS_WEAK_SET_TYPE) \
V(JS_PROMISE_CAPABILITY_TYPE) \
@ -760,11 +757,8 @@ enum InstanceType {
JS_DATA_VIEW_TYPE,
JS_SET_TYPE,
JS_MAP_TYPE,
JS_SET_KEY_VALUE_ITERATOR_TYPE,
JS_SET_VALUE_ITERATOR_TYPE,
JS_MAP_KEY_ITERATOR_TYPE,
JS_MAP_KEY_VALUE_ITERATOR_TYPE,
JS_MAP_VALUE_ITERATOR_TYPE,
JS_SET_ITERATOR_TYPE,
JS_MAP_ITERATOR_TYPE,
JS_WEAK_MAP_TYPE,
JS_WEAK_SET_TYPE,
JS_PROMISE_CAPABILITY_TYPE,

View File

@ -487,7 +487,6 @@ class OrderedHashTable : public FixedArray {
static const int kNumberOfDeletedElementsIndex = kNumberOfElementsIndex + 1;
static const int kNumberOfBucketsIndex = kNumberOfDeletedElementsIndex + 1;
static const int kHashTableStartIndex = kNumberOfBucketsIndex + 1;
static const int kRemovedHolesIndex = kHashTableStartIndex;
static constexpr const int kNumberOfElementsOffset =
FixedArray::OffsetOfElementAt(kNumberOfElementsIndex);
@ -499,8 +498,6 @@ class OrderedHashTable : public FixedArray {
FixedArray::OffsetOfElementAt(kNumberOfBucketsIndex);
static constexpr const int kHashTableStartOffset =
FixedArray::OffsetOfElementAt(kHashTableStartIndex);
static constexpr const int kRemovedHolesOffset =
FixedArray::OffsetOfElementAt(kRemovedHolesIndex);
static const int kEntrySize = entrysize + 1;
static const int kChainOffset = entrysize;
@ -539,6 +536,8 @@ class OrderedHashTable : public FixedArray {
void SetRemovedIndexAt(int index, int removed_index) {
return set(kRemovedHolesIndex + index, Smi::FromInt(removed_index));
}
static const int kRemovedHolesIndex = kHashTableStartIndex;
};
class OrderedHashSet : public OrderedHashTable<OrderedHashSet, 1> {
@ -857,13 +856,19 @@ class OrderedHashTableIterator : public JSObject {
// [index]: The index into the data table.
DECL_ACCESSORS(index, Object)
// [kind]: The kind of iteration this is. One of the [Kind] enum values.
DECL_ACCESSORS(kind, Object)
#ifdef OBJECT_PRINT
void OrderedHashTableIteratorPrint(std::ostream& os); // NOLINT
#endif
static const int kTableOffset = JSObject::kHeaderSize;
static const int kIndexOffset = kTableOffset + kPointerSize;
static const int kSize = kIndexOffset + kPointerSize;
static const int kKindOffset = kIndexOffset + kPointerSize;
static const int kSize = kKindOffset + kPointerSize;
enum Kind { kKindKeys = 1, kKindValues = 2, kKindEntries = 3 };
// Whether the iterator has more elements. This needs to be called before
// calling |CurrentKey| and/or |CurrentValue|.

View File

@ -80,9 +80,24 @@ RUNTIME_FUNCTION(Runtime_SetIteratorClone) {
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
return *isolate->factory()->NewJSSetIterator(
handle(holder->map(), isolate),
handle(OrderedHashSet::cast(holder->table()), isolate),
Smi::cast(holder->index())->value());
Smi::cast(holder->index())->value(),
static_cast<JSSetIterator::Kind>(Smi::cast(holder->kind())->value()));
}
// The array returned contains the following information:
// 0: HasMore flag
// 1: Iteration index
// 2: Iteration kind
RUNTIME_FUNCTION(Runtime_SetIteratorDetails) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSSetIterator, holder, 0);
Handle<FixedArray> details = isolate->factory()->NewFixedArray(4);
details->set(0, isolate->heap()->ToBoolean(holder->HasMore()));
details->set(1, holder->index());
details->set(2, holder->kind());
return *isolate->factory()->NewJSArrayWithElements(details);
}
@ -120,11 +135,28 @@ RUNTIME_FUNCTION(Runtime_MapIteratorClone) {
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
return *isolate->factory()->NewJSMapIterator(
handle(holder->map(), isolate),
handle(OrderedHashMap::cast(holder->table()), isolate),
Smi::cast(holder->index())->value());
Smi::cast(holder->index())->value(),
static_cast<JSMapIterator::Kind>(Smi::cast(holder->kind())->value()));
}
// The array returned contains the following information:
// 0: HasMore flag
// 1: Iteration index
// 2: Iteration kind
RUNTIME_FUNCTION(Runtime_MapIteratorDetails) {
HandleScope scope(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_HANDLE_CHECKED(JSMapIterator, holder, 0);
Handle<FixedArray> details = isolate->factory()->NewFixedArray(4);
details->set(0, isolate->heap()->ToBoolean(holder->HasMore()));
details->set(1, holder->index());
details->set(2, holder->kind());
return *isolate->factory()->NewJSArrayWithElements(details);
}
RUNTIME_FUNCTION(Runtime_GetWeakMapEntries) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
@ -228,6 +260,20 @@ RUNTIME_FUNCTION(Runtime_IsJSSet) {
return isolate->heap()->ToBoolean(obj->IsJSSet());
}
RUNTIME_FUNCTION(Runtime_IsJSMapIterator) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSMapIterator());
}
RUNTIME_FUNCTION(Runtime_IsJSSetIterator) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());
CONVERT_ARG_CHECKED(Object, obj, 0);
return isolate->heap()->ToBoolean(obj->IsJSSetIterator());
}
RUNTIME_FUNCTION(Runtime_IsJSWeakMap) {
SealHandleScope shs(isolate);
DCHECK_EQ(1, args.length());

View File

@ -147,19 +147,18 @@ static MaybeHandle<JSArray> GetIteratorInternalProperties(
Isolate* isolate, Handle<IteratorType> object) {
Factory* factory = isolate->factory();
Handle<IteratorType> iterator = Handle<IteratorType>::cast(object);
CHECK(iterator->kind()->IsSmi());
const char* kind = NULL;
switch (iterator->map()->instance_type()) {
case JS_MAP_KEY_ITERATOR_TYPE:
switch (Smi::cast(iterator->kind())->value()) {
case IteratorType::kKindKeys:
kind = "keys";
break;
case JS_MAP_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
kind = "entries";
break;
case JS_MAP_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
case IteratorType::kKindValues:
kind = "values";
break;
case IteratorType::kKindEntries:
kind = "entries";
break;
default:
UNREACHABLE();
}

View File

@ -98,10 +98,12 @@ namespace internal {
F(SetGrow, 1, 1) \
F(SetShrink, 1, 1) \
F(SetIteratorClone, 1, 1) \
F(SetIteratorDetails, 1, 1) \
F(MapInitialize, 1, 1) \
F(MapShrink, 1, 1) \
F(MapGrow, 1, 1) \
F(MapIteratorClone, 1, 1) \
F(MapIteratorDetails, 1, 1) \
F(GetWeakMapEntries, 2, 1) \
F(WeakCollectionInitialize, 1, 1) \
F(WeakCollectionGet, 3, 1) \
@ -111,6 +113,8 @@ namespace internal {
F(GetWeakSetValues, 2, 1) \
F(IsJSMap, 1, 1) \
F(IsJSSet, 1, 1) \
F(IsJSMapIterator, 1, 1) \
F(IsJSSetIterator, 1, 1) \
F(IsJSWeakMap, 1, 1) \
F(IsJSWeakSet, 1, 1)

View File

@ -103,60 +103,57 @@ INSTANCE_TYPES = {
199: "JS_DATA_VIEW_TYPE",
200: "JS_SET_TYPE",
201: "JS_MAP_TYPE",
202: "JS_SET_KEY_VALUE_ITERATOR_TYPE",
203: "JS_SET_VALUE_ITERATOR_TYPE",
204: "JS_MAP_KEY_ITERATOR_TYPE",
205: "JS_MAP_KEY_VALUE_ITERATOR_TYPE",
206: "JS_MAP_VALUE_ITERATOR_TYPE",
207: "JS_WEAK_MAP_TYPE",
208: "JS_WEAK_SET_TYPE",
209: "JS_PROMISE_CAPABILITY_TYPE",
210: "JS_PROMISE_TYPE",
211: "JS_REGEXP_TYPE",
212: "JS_ERROR_TYPE",
213: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
214: "JS_STRING_ITERATOR_TYPE",
215: "JS_TYPED_ARRAY_KEY_ITERATOR_TYPE",
216: "JS_FAST_ARRAY_KEY_ITERATOR_TYPE",
217: "JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE",
218: "JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE",
219: "JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE",
220: "JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE",
221: "JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE",
222: "JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
223: "JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
224: "JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
225: "JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE",
226: "JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE",
227: "JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
228: "JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
229: "JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE",
230: "JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE",
231: "JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
232: "JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
233: "JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE",
234: "JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE",
235: "JS_INT8_ARRAY_VALUE_ITERATOR_TYPE",
236: "JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE",
237: "JS_INT16_ARRAY_VALUE_ITERATOR_TYPE",
238: "JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE",
239: "JS_INT32_ARRAY_VALUE_ITERATOR_TYPE",
240: "JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE",
241: "JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE",
242: "JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE",
243: "JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE",
244: "JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE",
245: "JS_FAST_ARRAY_VALUE_ITERATOR_TYPE",
246: "JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE",
247: "JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
248: "JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
249: "JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE",
250: "WASM_INSTANCE_TYPE",
251: "WASM_MEMORY_TYPE",
252: "WASM_MODULE_TYPE",
253: "WASM_TABLE_TYPE",
254: "JS_BOUND_FUNCTION_TYPE",
255: "JS_FUNCTION_TYPE",
202: "JS_SET_ITERATOR_TYPE",
203: "JS_MAP_ITERATOR_TYPE",
204: "JS_WEAK_MAP_TYPE",
205: "JS_WEAK_SET_TYPE",
206: "JS_PROMISE_CAPABILITY_TYPE",
207: "JS_PROMISE_TYPE",
208: "JS_REGEXP_TYPE",
209: "JS_ERROR_TYPE",
210: "JS_ASYNC_FROM_SYNC_ITERATOR_TYPE",
211: "JS_STRING_ITERATOR_TYPE",
212: "JS_TYPED_ARRAY_KEY_ITERATOR_TYPE",
213: "JS_FAST_ARRAY_KEY_ITERATOR_TYPE",
214: "JS_GENERIC_ARRAY_KEY_ITERATOR_TYPE",
215: "JS_UINT8_ARRAY_KEY_VALUE_ITERATOR_TYPE",
216: "JS_INT8_ARRAY_KEY_VALUE_ITERATOR_TYPE",
217: "JS_UINT16_ARRAY_KEY_VALUE_ITERATOR_TYPE",
218: "JS_INT16_ARRAY_KEY_VALUE_ITERATOR_TYPE",
219: "JS_UINT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
220: "JS_INT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
221: "JS_FLOAT32_ARRAY_KEY_VALUE_ITERATOR_TYPE",
222: "JS_FLOAT64_ARRAY_KEY_VALUE_ITERATOR_TYPE",
223: "JS_UINT8_CLAMPED_ARRAY_KEY_VALUE_ITERATOR_TYPE",
224: "JS_FAST_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
225: "JS_FAST_HOLEY_SMI_ARRAY_KEY_VALUE_ITERATOR_TYPE",
226: "JS_FAST_ARRAY_KEY_VALUE_ITERATOR_TYPE",
227: "JS_FAST_HOLEY_ARRAY_KEY_VALUE_ITERATOR_TYPE",
228: "JS_FAST_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
229: "JS_FAST_HOLEY_DOUBLE_ARRAY_KEY_VALUE_ITERATOR_TYPE",
230: "JS_GENERIC_ARRAY_KEY_VALUE_ITERATOR_TYPE",
231: "JS_UINT8_ARRAY_VALUE_ITERATOR_TYPE",
232: "JS_INT8_ARRAY_VALUE_ITERATOR_TYPE",
233: "JS_UINT16_ARRAY_VALUE_ITERATOR_TYPE",
234: "JS_INT16_ARRAY_VALUE_ITERATOR_TYPE",
235: "JS_UINT32_ARRAY_VALUE_ITERATOR_TYPE",
236: "JS_INT32_ARRAY_VALUE_ITERATOR_TYPE",
237: "JS_FLOAT32_ARRAY_VALUE_ITERATOR_TYPE",
238: "JS_FLOAT64_ARRAY_VALUE_ITERATOR_TYPE",
239: "JS_UINT8_CLAMPED_ARRAY_VALUE_ITERATOR_TYPE",
240: "JS_FAST_SMI_ARRAY_VALUE_ITERATOR_TYPE",
241: "JS_FAST_HOLEY_SMI_ARRAY_VALUE_ITERATOR_TYPE",
242: "JS_FAST_ARRAY_VALUE_ITERATOR_TYPE",
243: "JS_FAST_HOLEY_ARRAY_VALUE_ITERATOR_TYPE",
244: "JS_FAST_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
245: "JS_FAST_HOLEY_DOUBLE_ARRAY_VALUE_ITERATOR_TYPE",
246: "JS_GENERIC_ARRAY_VALUE_ITERATOR_TYPE",
247: "WASM_INSTANCE_TYPE",
248: "WASM_MEMORY_TYPE",
249: "WASM_MODULE_TYPE",
250: "WASM_TABLE_TYPE",
251: "JS_BOUND_FUNCTION_TYPE",
252: "JS_FUNCTION_TYPE",
}
# List of known V8 maps.
@ -248,7 +245,7 @@ KNOWN_MAPS = {
0x03ee1: (190, "ExternalMap"),
0x03f39: (106, "NativeSourceStringMap"),
0x03f91: (152, "InterceptorInfoMap"),
0x03fe9: (209, "JSPromiseCapabilityMap"),
0x03fe9: (206, "JSPromiseCapabilityMap"),
0x04041: (149, "AccessorInfoMap"),
0x04099: (150, "AccessorPairMap"),
0x040f1: (151, "AccessCheckInfoMap"),