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:
parent
cf8d672d96
commit
5a6e24e9e4
27
src/api.cc
27
src/api.cc
@ -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);
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) \
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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) \
|
||||
|
@ -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) \
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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(
|
||||
|
@ -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);
|
||||
|
@ -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) \
|
||||
|
@ -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');
|
||||
|
@ -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:
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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";
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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,
|
||||
|
@ -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|.
|
||||
|
@ -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());
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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"),
|
||||
|
Loading…
Reference in New Issue
Block a user