Commit 23fa5061 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Precompute inlineability of array iteration builtins per map.

Bug: v8:7790
Change-Id: Ife2d4d19bc40ec195974c5302677fef4ab442fa2
Reviewed-on: https://chromium-review.googlesource.com/c/1398721
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#58666}
parent d65de040
......@@ -996,17 +996,6 @@ void JSCallReducer::WireInLoopEnd(Node* loop, Node* eloop, Node* vloop, Node* k,
}
namespace {
bool CanInlineArrayIteratingBuiltin(Isolate* isolate, MapRef& receiver_map) {
receiver_map.SerializePrototype();
if (!receiver_map.prototype().IsJSArray()) return false;
JSArrayRef receiver_prototype = receiver_map.prototype().AsJSArray();
return receiver_map.instance_type() == JS_ARRAY_TYPE &&
IsFastElementsKind(receiver_map.elements_kind()) &&
isolate->IsNoElementsProtectorIntact() &&
isolate->IsAnyInitialArrayPrototype(receiver_prototype.object());
}
bool CanInlineArrayIteratingBuiltin(JSHeapBroker* broker,
ZoneHandleSet<Map> receiver_maps,
ElementsKind* kind_return) {
......@@ -1014,16 +1003,13 @@ bool CanInlineArrayIteratingBuiltin(JSHeapBroker* broker,
*kind_return = MapRef(broker, receiver_maps[0]).elements_kind();
for (auto receiver_map : receiver_maps) {
MapRef map(broker, receiver_map);
if (!CanInlineArrayIteratingBuiltin(broker->isolate(), map)) {
return false;
}
if (!UnionElementsKindUptoSize(kind_return, map.elements_kind())) {
if (!map.supports_fast_array_iteration() ||
!UnionElementsKindUptoSize(kind_return, map.elements_kind())) {
return false;
}
}
return true;
}
} // namespace
Reduction JSCallReducer::ReduceArrayForEach(
......@@ -2559,8 +2545,7 @@ Reduction JSCallReducer::ReduceArrayIndexOfIncludes(
return NoChange();
MapRef receiver_map(broker(), map);
if (!CanInlineArrayIteratingBuiltin(isolate(), receiver_map))
return NoChange();
if (!receiver_map.supports_fast_array_iteration()) return NoChange();
ElementsKind const elements_kind = receiver_map.elements_kind();
if (IsHoleyElementsKind(elements_kind)) {
......@@ -4770,9 +4755,7 @@ Reduction JSCallReducer::ReduceArrayPrototypeSlice(Node* node) {
bool can_be_holey = false;
for (Handle<Map> map : receiver_maps) {
MapRef receiver_map(broker(), map);
if (!CanInlineArrayIteratingBuiltin(isolate(), receiver_map)) {
return NoChange();
}
if (!receiver_map.supports_fast_array_iteration()) return NoChange();
if (IsHoleyElementsKind(receiver_map.elements_kind())) {
can_be_holey = true;
......
......@@ -649,6 +649,9 @@ class MapData : public HeapObjectData {
int constructor_function_index() const { return constructor_function_index_; }
int NextFreePropertyIndex() const { return next_free_property_index_; }
int UnusedPropertyFields() const { return unused_property_fields_; }
bool supports_fast_array_iteration() const {
return supports_fast_array_iteration_;
}
bool supports_fast_array_resize() const {
return supports_fast_array_resize_;
}
......@@ -694,6 +697,7 @@ class MapData : public HeapObjectData {
int const constructor_function_index_;
int const next_free_property_index_;
int const unused_property_fields_;
bool const supports_fast_array_iteration_;
bool const supports_fast_array_resize_;
bool serialized_elements_kind_generalizations_ = false;
......@@ -766,16 +770,19 @@ bool IsReadOnlyLengthDescriptor(Isolate* isolate, Handle<Map> jsarray_map) {
return descriptors->GetDetails(number).IsReadOnly();
}
bool SupportsFastArrayResize(Isolate* isolate, Handle<Map> map) {
bool SupportsFastArrayIteration(Isolate* isolate, Handle<Map> map) {
return map->instance_type() == JS_ARRAY_TYPE &&
IsFastElementsKind(map->elements_kind()) && map->is_extensible() &&
IsFastElementsKind(map->elements_kind()) &&
map->prototype()->IsJSArray() &&
isolate->IsAnyInitialArrayPrototype(
handle(JSArray::cast(map->prototype()), isolate)) &&
!map->is_dictionary_map() &&
!IsReadOnlyLengthDescriptor(isolate, map) &&
isolate->IsNoElementsProtectorIntact();
}
bool SupportsFastArrayResize(Isolate* isolate, Handle<Map> map) {
return SupportsFastArrayIteration(isolate, map) && map->is_extensible() &&
!map->is_dictionary_map() && !IsReadOnlyLengthDescriptor(isolate, map);
}
} // namespace
MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object)
......@@ -799,6 +806,8 @@ MapData::MapData(JSHeapBroker* broker, ObjectData** storage, Handle<Map> object)
: Map::kNoConstructorFunctionIndex),
next_free_property_index_(object->NextFreePropertyIndex()),
unused_property_fields_(object->UnusedPropertyFields()),
supports_fast_array_iteration_(
SupportsFastArrayIteration(broker->isolate(), object)),
supports_fast_array_resize_(
SupportsFastArrayResize(broker->isolate(), object)),
elements_kind_generalizations_(broker->zone()) {}
......@@ -1847,6 +1856,15 @@ base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
return base::Optional<MapRef>();
}
bool MapRef::supports_fast_array_iteration() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
AllowHandleDereference allow_handle_dereference;
AllowHandleAllocation handle_allocation;
return SupportsFastArrayIteration(broker()->isolate(), object());
}
return data()->AsMap()->supports_fast_array_iteration();
}
bool MapRef::supports_fast_array_resize() const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
AllowHandleDereference allow_handle_dereference;
......
......@@ -433,6 +433,7 @@ class MapRef : public HeapObjectRef {
bool is_undetectable() const;
bool is_callable() const;
bool has_hidden_prototype() const;
bool supports_fast_array_iteration() const;
bool supports_fast_array_resize() const;
#define DEF_TESTER(Type, ...) bool Is##Type##Map() const;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment