Commit 53c3c6a9 authored by Georg Neis's avatar Georg Neis Committed by Commit Bot

[turbofan] Precompute ElementsKind generalizations for initial maps.

Bug: v8:7790
Change-Id: I18512b508127c48ab0a1dc5a6a221d0f491bb5fe
Reviewed-on: https://chromium-review.googlesource.com/1175917
Commit-Queue: Georg Neis <neis@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#55171}
parent 12857348
...@@ -17,7 +17,6 @@ namespace internal { ...@@ -17,7 +17,6 @@ namespace internal {
namespace compiler { namespace compiler {
Reduction JSContextSpecialization::Reduce(Node* node) { Reduction JSContextSpecialization::Reduce(Node* node) {
DisallowHeapAccess no_heap_access;
switch (node->opcode()) { switch (node->opcode()) {
case IrOpcode::kParameter: case IrOpcode::kParameter:
return ReduceParameter(node); return ReduceParameter(node);
......
...@@ -78,13 +78,7 @@ class JSFunctionData : public JSObjectData { ...@@ -78,13 +78,7 @@ class JSFunctionData : public JSObjectData {
ObjectData* const shared; ObjectData* const shared;
JSFunctionData(JSHeapBroker* broker_, Handle<JSFunction> object_, JSFunctionData(JSHeapBroker* broker_, Handle<JSFunction> object_,
HeapObjectType type_) HeapObjectType type_);
: JSObjectData(broker_, object_, type_),
global_proxy(GET_OR_CREATE(global_proxy)),
prototype_or_initial_map(object_->map()->has_prototype_slot()
? GET_OR_CREATE(prototype_or_initial_map)
: nullptr),
shared(GET_OR_CREATE(shared)) {}
}; };
class JSRegExpData : public JSObjectData {}; class JSRegExpData : public JSObjectData {};
...@@ -99,6 +93,7 @@ class ContextData : public HeapObjectData { ...@@ -99,6 +93,7 @@ class ContextData : public HeapObjectData {
}; };
#define NATIVE_CONTEXT_DATA(V) \ #define NATIVE_CONTEXT_DATA(V) \
V(array_function) \
V(fast_aliased_arguments_map) \ V(fast_aliased_arguments_map) \
V(initial_array_iterator_map) \ V(initial_array_iterator_map) \
V(iterator_result_map) \ V(iterator_result_map) \
...@@ -168,18 +163,66 @@ class AllocationSiteData : public HeapObjectData {}; ...@@ -168,18 +163,66 @@ class AllocationSiteData : public HeapObjectData {};
class MapData : public HeapObjectData { class MapData : public HeapObjectData {
public: public:
InstanceType const instance_type;
int const instance_size; int const instance_size;
byte const bit_field; byte const bit_field;
byte const bit_field2; byte const bit_field2;
uint32_t const bit_field3; uint32_t const bit_field3;
MapData(JSHeapBroker* broker_, Handle<Map> object_, HeapObjectType type_) MapData(JSHeapBroker* broker_, Handle<Map> object_, HeapObjectType type_);
// Extra information.
void SerializeElementsKindGeneralizations();
const ZoneVector<MapData*>& elements_kind_generalizations() {
return elements_kind_generalizations_;
}
private:
ZoneVector<MapData*> elements_kind_generalizations_;
};
MapData::MapData(JSHeapBroker* broker_, Handle<Map> object_,
HeapObjectType type_)
: HeapObjectData(broker_, object_, type_), : HeapObjectData(broker_, object_, type_),
instance_type(object_->instance_type()),
instance_size(object_->instance_size()), instance_size(object_->instance_size()),
bit_field(object_->bit_field()), bit_field(object_->bit_field()),
bit_field2(object_->bit_field2()), bit_field2(object_->bit_field2()),
bit_field3(object_->bit_field3()) {} bit_field3(object_->bit_field3()),
}; elements_kind_generalizations_(broker->zone()) {}
JSFunctionData::JSFunctionData(JSHeapBroker* broker_,
Handle<JSFunction> object_, HeapObjectType type_)
: JSObjectData(broker_, object_, type_),
global_proxy(GET_OR_CREATE(global_proxy)),
prototype_or_initial_map(object_->map()->has_prototype_slot()
? GET_OR_CREATE(prototype_or_initial_map)
: nullptr),
shared(GET_OR_CREATE(shared)) {
if (prototype_or_initial_map != nullptr &&
prototype_or_initial_map->IsMap()) {
MapData* initial_map = prototype_or_initial_map->AsMap();
if (initial_map->instance_type == JS_ARRAY_TYPE) {
initial_map->SerializeElementsKindGeneralizations();
}
}
}
void MapData::SerializeElementsKindGeneralizations() {
broker->Trace("Computing ElementsKind generalizations of %p.\n", *object);
DCHECK_EQ(instance_type, JS_ARRAY_TYPE);
MapRef self(this);
ElementsKind from_kind = self.elements_kind();
for (int i = FIRST_FAST_ELEMENTS_KIND; i <= LAST_FAST_ELEMENTS_KIND; i++) {
ElementsKind to_kind = static_cast<ElementsKind>(i);
if (IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
Handle<Map> target =
Map::AsElementsKind(broker->isolate(), self.object<Map>(), to_kind);
elements_kind_generalizations_.push_back(
broker->GetOrCreateData(target)->AsMap());
}
}
}
class FixedArrayBaseData : public HeapObjectData {}; class FixedArrayBaseData : public HeapObjectData {};
class FixedArrayData : public FixedArrayBaseData {}; class FixedArrayData : public FixedArrayBaseData {};
...@@ -353,6 +396,8 @@ void JSHeapBroker::SerializeStandardObjects() { ...@@ -353,6 +396,8 @@ void JSHeapBroker::SerializeStandardObjects() {
GetOrCreateData(b->builtin_handle(id)); GetOrCreateData(b->builtin_handle(id));
} }
} }
Trace("Finished serializing standard objects.\n");
} }
HeapObjectType JSHeapBroker::HeapObjectTypeFromMap(Map* map) const { HeapObjectType JSHeapBroker::HeapObjectTypeFromMap(Map* map) const {
...@@ -461,13 +506,23 @@ void JSFunctionRef::EnsureHasInitialMap() const { ...@@ -461,13 +506,23 @@ void JSFunctionRef::EnsureHasInitialMap() const {
JSFunction::EnsureHasInitialMap(object<JSFunction>()); JSFunction::EnsureHasInitialMap(object<JSFunction>());
} }
// TODO(mslekova): Pre-compute these on the main thread.
base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const { base::Optional<MapRef> MapRef::AsElementsKind(ElementsKind kind) const {
if (broker()->mode() == JSHeapBroker::kDisabled) {
AllowHandleAllocation handle_allocation; AllowHandleAllocation handle_allocation;
AllowHeapAllocation heap_allocation; AllowHeapAllocation heap_allocation;
AllowHandleDereference allow_handle_dereference; AllowHandleDereference allow_handle_dereference;
return MapRef(broker(), return MapRef(broker(), Map::AsElementsKind(broker()->isolate(),
Map::AsElementsKind(broker()->isolate(), object<Map>(), kind)); object<Map>(), kind));
} else {
if (kind == elements_kind()) return *this;
const ZoneVector<MapData*>& elements_kind_generalizations =
data()->AsMap()->elements_kind_generalizations();
for (auto data : elements_kind_generalizations) {
MapRef map(data);
if (map.elements_kind() == kind) return map;
}
return base::Optional<MapRef>();
}
} }
int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() const { int JSFunctionRef::InitialMapInstanceSizeWithMinSlack() 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