[turbofan] Brokerize closure creation.
Bug: v8:7790 Change-Id: Iff4f0561901c454fc3facfeb152727d3994b4f98 Reviewed-on: https://chromium-review.googlesource.com/1127947 Commit-Queue: Jaroslav Sevcik <jarin@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Cr-Commit-Position: refs/heads/master@{#54304}
This commit is contained in:
parent
16de08ea72
commit
289729bb6d
@ -85,9 +85,9 @@ FieldAccess AccessBuilder::ForJSObjectElements() {
|
|||||||
|
|
||||||
|
|
||||||
// static
|
// static
|
||||||
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
|
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(const MapRef& map,
|
||||||
int index) {
|
int index) {
|
||||||
int const offset = map->GetInObjectPropertyOffset(index);
|
int const offset = map.GetInObjectPropertyOffset(index);
|
||||||
FieldAccess access = {kTaggedBase, offset,
|
FieldAccess access = {kTaggedBase, offset,
|
||||||
MaybeHandle<Name>(), MaybeHandle<Map>(),
|
MaybeHandle<Name>(), MaybeHandle<Map>(),
|
||||||
Type::NonInternal(), MachineType::AnyTagged(),
|
Type::NonInternal(), MachineType::AnyTagged(),
|
||||||
|
@ -48,7 +48,7 @@ class V8_EXPORT_PRIVATE AccessBuilder final
|
|||||||
static FieldAccess ForJSObjectElements();
|
static FieldAccess ForJSObjectElements();
|
||||||
|
|
||||||
// Provides access to JSObject inobject property fields.
|
// Provides access to JSObject inobject property fields.
|
||||||
static FieldAccess ForJSObjectInObjectProperty(Handle<Map> map, int index);
|
static FieldAccess ForJSObjectInObjectProperty(const MapRef& map, int index);
|
||||||
static FieldAccess ForJSObjectOffset(
|
static FieldAccess ForJSObjectOffset(
|
||||||
int offset, WriteBarrierKind write_barrier_kind = kFullWriteBarrier);
|
int offset, WriteBarrierKind write_barrier_kind = kFullWriteBarrier);
|
||||||
|
|
||||||
|
@ -1739,8 +1739,9 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node,
|
|||||||
ab.Store(AccessBuilder::ForJSArrayLength(packed_kind),
|
ab.Store(AccessBuilder::ForJSArrayLength(packed_kind),
|
||||||
jsgraph()->ZeroConstant());
|
jsgraph()->ZeroConstant());
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
ab.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
ab.Store(
|
||||||
jsgraph()->UndefinedConstant());
|
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
a = effect = ab.Finish();
|
a = effect = ab.Finish();
|
||||||
}
|
}
|
||||||
|
@ -150,8 +150,9 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
|
|||||||
a.Store(AccessBuilder::ForJSObjectElements(),
|
a.Store(AccessBuilder::ForJSObjectElements(),
|
||||||
jsgraph()->EmptyFixedArrayConstant());
|
jsgraph()->EmptyFixedArrayConstant());
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
a.Store(
|
||||||
jsgraph()->UndefinedConstant());
|
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
RelaxControls(node);
|
RelaxControls(node);
|
||||||
a.FinishAndChange(node);
|
a.FinishAndChange(node);
|
||||||
@ -475,8 +476,9 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
|
|||||||
|
|
||||||
// Handle in-object properties, too.
|
// Handle in-object properties, too.
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
a.Store(
|
||||||
undefined);
|
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
|
undefined);
|
||||||
}
|
}
|
||||||
a.FinishAndChange(node);
|
a.FinishAndChange(node);
|
||||||
return Changed(node);
|
return Changed(node);
|
||||||
@ -526,7 +528,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
|
|||||||
a.Store(AccessBuilder::ForJSArrayLength(initial_map->elements_kind()),
|
a.Store(AccessBuilder::ForJSArrayLength(initial_map->elements_kind()),
|
||||||
length);
|
length);
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
jsgraph()->UndefinedConstant());
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
RelaxControls(node);
|
RelaxControls(node);
|
||||||
@ -571,7 +573,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
|
|||||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||||
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
jsgraph()->UndefinedConstant());
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
RelaxControls(node);
|
RelaxControls(node);
|
||||||
@ -627,7 +629,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node,
|
|||||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||||
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
||||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||||
jsgraph()->UndefinedConstant());
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
RelaxControls(node);
|
RelaxControls(node);
|
||||||
@ -970,11 +972,12 @@ Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
||||||
|
DisallowHandleDereference disallow_dereference;
|
||||||
DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
|
DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
|
||||||
CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
|
CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
|
||||||
Handle<SharedFunctionInfo> shared = p.shared_info();
|
SharedFunctionInfoRef shared(p.shared_info());
|
||||||
Handle<FeedbackCell> feedback_cell = p.feedback_cell();
|
HeapObjectRef feedback_cell(p.feedback_cell());
|
||||||
Handle<Code> code = p.code();
|
HeapObjectRef code(p.code());
|
||||||
Node* effect = NodeProperties::GetEffectInput(node);
|
Node* effect = NodeProperties::GetEffectInput(node);
|
||||||
Node* control = NodeProperties::GetControlInput(node);
|
Node* control = NodeProperties::GetControlInput(node);
|
||||||
Node* context = NodeProperties::GetContextInput(node);
|
Node* context = NodeProperties::GetContextInput(node);
|
||||||
@ -982,18 +985,15 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
|||||||
// Use inline allocation of closures only for instantiation sites that have
|
// Use inline allocation of closures only for instantiation sites that have
|
||||||
// seen more than one instantiation, this simplifies the generated code and
|
// seen more than one instantiation, this simplifies the generated code and
|
||||||
// also serves as a heuristic of which allocation sites benefit from it.
|
// also serves as a heuristic of which allocation sites benefit from it.
|
||||||
if (feedback_cell->map() !=
|
if (!feedback_cell.map(js_heap_broker())
|
||||||
ReadOnlyRoots(isolate()).many_closures_cell_map()) {
|
.equals(MapRef(factory()->many_closures_cell_map()))) {
|
||||||
// The generic path can only create closures for user functions.
|
|
||||||
DCHECK_EQ(isolate()->builtins()->builtin(Builtins::kCompileLazy), *code);
|
|
||||||
return NoChange();
|
return NoChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
Handle<Map> function_map(
|
MapRef function_map = native_context_ref().GetFunctionMapFromIndex(
|
||||||
Map::cast(native_context()->get(shared->function_map_index())),
|
js_heap_broker(), shared.function_map_index());
|
||||||
isolate());
|
DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
|
||||||
DCHECK(!function_map->IsInobjectSlackTrackingInProgress());
|
DCHECK(!function_map.is_dictionary_map());
|
||||||
DCHECK(!function_map->is_dictionary_map());
|
|
||||||
|
|
||||||
// TODO(turbofan): We should use the pretenure flag from {p} here,
|
// TODO(turbofan): We should use the pretenure flag from {p} here,
|
||||||
// but currently the heuristic in the parser works against us, as
|
// but currently the heuristic in the parser works against us, as
|
||||||
@ -1009,7 +1009,7 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
|||||||
// Emit code to allocate the JSFunction instance.
|
// Emit code to allocate the JSFunction instance.
|
||||||
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
||||||
AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control);
|
AllocationBuilder a(jsgraph(), js_heap_broker(), effect, control);
|
||||||
a.Allocate(function_map->instance_size(), pretenure, Type::Function());
|
a.Allocate(function_map.instance_size(), pretenure, Type::Function());
|
||||||
a.Store(AccessBuilder::ForMap(), function_map);
|
a.Store(AccessBuilder::ForMap(), function_map);
|
||||||
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
|
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(),
|
||||||
jsgraph()->EmptyFixedArrayConstant());
|
jsgraph()->EmptyFixedArrayConstant());
|
||||||
@ -1020,12 +1020,12 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
|||||||
a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
|
a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
|
||||||
a.Store(AccessBuilder::ForJSFunctionCode(), code);
|
a.Store(AccessBuilder::ForJSFunctionCode(), code);
|
||||||
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
||||||
if (function_map->has_prototype_slot()) {
|
if (function_map.has_prototype_slot()) {
|
||||||
a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
|
a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
|
||||||
jsgraph()->TheHoleConstant());
|
jsgraph()->TheHoleConstant());
|
||||||
STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kPointerSize);
|
STATIC_ASSERT(JSFunction::kSizeWithPrototype == 8 * kPointerSize);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < function_map->GetInObjectProperties(); i++) {
|
for (int i = 0; i < function_map.GetInObjectProperties(); i++) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
|
a.Store(AccessBuilder::ForJSObjectInObjectProperty(function_map, i),
|
||||||
jsgraph()->UndefinedConstant());
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
@ -1209,7 +1209,7 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
|
|||||||
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
|
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
|
||||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||||
for (int i = 0; i < map->GetInObjectProperties(); i++) {
|
for (int i = 0; i < map->GetInObjectProperties(); i++) {
|
||||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
|
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(map), i),
|
||||||
jsgraph()->UndefinedConstant());
|
jsgraph()->UndefinedConstant());
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1712,8 +1712,8 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
|
|||||||
int const boilerplate_length = boilerplate_map.GetInObjectProperties();
|
int const boilerplate_length = boilerplate_map.GetInObjectProperties();
|
||||||
for (int index = static_cast<int>(inobject_fields.size());
|
for (int index = static_cast<int>(inobject_fields.size());
|
||||||
index < boilerplate_length; ++index) {
|
index < boilerplate_length; ++index) {
|
||||||
FieldAccess access = AccessBuilder::ForJSObjectInObjectProperty(
|
FieldAccess access =
|
||||||
boilerplate_map.object<Map>(), index);
|
AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
|
||||||
Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
|
Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
|
||||||
inobject_fields.push_back(std::make_pair(access, value));
|
inobject_fields.push_back(std::make_pair(access, value));
|
||||||
}
|
}
|
||||||
|
@ -63,6 +63,10 @@ bool ObjectRef::IsSmi() const {
|
|||||||
|
|
||||||
int ObjectRef::AsSmi() const { return object<Smi>()->value(); }
|
int ObjectRef::AsSmi() const { return object<Smi>()->value(); }
|
||||||
|
|
||||||
|
bool ObjectRef::equals(const ObjectRef& other) const {
|
||||||
|
return object<Object>().equals(other.object<Object>());
|
||||||
|
}
|
||||||
|
|
||||||
base::Optional<ContextRef> ContextRef::previous(
|
base::Optional<ContextRef> ContextRef::previous(
|
||||||
const JSHeapBroker* broker) const {
|
const JSHeapBroker* broker) const {
|
||||||
AllowHandleAllocation handle_allocation;
|
AllowHandleAllocation handle_allocation;
|
||||||
@ -411,6 +415,16 @@ bool MapRef::IsFixedCowArrayMap(const JSHeapBroker* broker) const {
|
|||||||
ReadOnlyRoots(broker->isolate()).fixed_cow_array_map();
|
ReadOnlyRoots(broker->isolate()).fixed_cow_array_map();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int MapRef::GetInObjectPropertyOffset(int index) const {
|
||||||
|
AllowHandleDereference allow_handle_dereference;
|
||||||
|
return object<Map>()->GetInObjectPropertyOffset(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool MapRef::has_prototype_slot() const {
|
||||||
|
AllowHandleDereference allow_handle_dereference;
|
||||||
|
return object<Map>()->has_prototype_slot();
|
||||||
|
}
|
||||||
|
|
||||||
ElementsKind JSArrayRef::GetElementsKind() const {
|
ElementsKind JSArrayRef::GetElementsKind() const {
|
||||||
AllowHandleDereference allow_handle_dereference;
|
AllowHandleDereference allow_handle_dereference;
|
||||||
return object<JSArray>()->GetElementsKind();
|
return object<JSArray>()->GetElementsKind();
|
||||||
@ -483,6 +497,11 @@ int SharedFunctionInfoRef::internal_formal_parameter_count() const {
|
|||||||
return object<SharedFunctionInfo>()->internal_formal_parameter_count();
|
return object<SharedFunctionInfo>()->internal_formal_parameter_count();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int SharedFunctionInfoRef::function_map_index() const {
|
||||||
|
AllowHandleDereference allow_handle_dereference;
|
||||||
|
return object<SharedFunctionInfo>()->function_map_index();
|
||||||
|
}
|
||||||
|
|
||||||
bool SharedFunctionInfoRef::has_duplicate_parameters() const {
|
bool SharedFunctionInfoRef::has_duplicate_parameters() const {
|
||||||
AllowHandleDereference allow_handle_dereference;
|
AllowHandleDereference allow_handle_dereference;
|
||||||
return object<SharedFunctionInfo>()->has_duplicate_parameters();
|
return object<SharedFunctionInfo>()->has_duplicate_parameters();
|
||||||
@ -558,6 +577,14 @@ MapRef NativeContextRef::map_key_value_iterator_map(
|
|||||||
broker->isolate()));
|
broker->isolate()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MapRef NativeContextRef::GetFunctionMapFromIndex(const JSHeapBroker* broker,
|
||||||
|
int index) const {
|
||||||
|
AllowHandleDereference allow_handle_dereference;
|
||||||
|
DCHECK_LE(index, Context::LAST_FUNCTION_MAP_INDEX);
|
||||||
|
DCHECK_GE(index, Context::FIRST_FUNCTION_MAP_INDEX);
|
||||||
|
return get(broker, index).AsMap();
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
} // namespace internal
|
} // namespace internal
|
||||||
} // namespace v8
|
} // namespace v8
|
||||||
|
@ -100,6 +100,8 @@ class ObjectRef {
|
|||||||
bool IsSmi() const;
|
bool IsSmi() const;
|
||||||
int AsSmi() const;
|
int AsSmi() const;
|
||||||
|
|
||||||
|
bool equals(const ObjectRef& other) const;
|
||||||
|
|
||||||
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
|
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
|
||||||
HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL)
|
HEAP_BROKER_KIND_LIST(HEAP_IS_METHOD_DECL)
|
||||||
#undef HEAP_IS_METHOD_DECL
|
#undef HEAP_IS_METHOD_DECL
|
||||||
@ -211,6 +213,8 @@ class NativeContextRef : public ContextRef {
|
|||||||
MapRef map_key_iterator_map(const JSHeapBroker* broker) const;
|
MapRef map_key_iterator_map(const JSHeapBroker* broker) const;
|
||||||
MapRef map_value_iterator_map(const JSHeapBroker* broker) const;
|
MapRef map_value_iterator_map(const JSHeapBroker* broker) const;
|
||||||
MapRef map_key_value_iterator_map(const JSHeapBroker* broker) const;
|
MapRef map_key_value_iterator_map(const JSHeapBroker* broker) const;
|
||||||
|
|
||||||
|
MapRef GetFunctionMapFromIndex(const JSHeapBroker* broker, int index) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class NameRef : public HeapObjectRef {
|
class NameRef : public HeapObjectRef {
|
||||||
@ -260,10 +264,14 @@ class MapRef : public HeapObjectRef {
|
|||||||
NameRef GetPropertyKey(const JSHeapBroker* broker, int i) const;
|
NameRef GetPropertyKey(const JSHeapBroker* broker, int i) const;
|
||||||
FieldIndex GetFieldIndexFor(int i) const;
|
FieldIndex GetFieldIndexFor(int i) const;
|
||||||
|
|
||||||
|
int GetInObjectPropertyOffset(int index) const;
|
||||||
|
|
||||||
bool IsJSArrayMap() const;
|
bool IsJSArrayMap() const;
|
||||||
bool IsFixedCowArrayMap(const JSHeapBroker* broker) const;
|
bool IsFixedCowArrayMap(const JSHeapBroker* broker) const;
|
||||||
bool is_dictionary_map() const;
|
bool is_dictionary_map() const;
|
||||||
|
|
||||||
|
bool has_prototype_slot() const;
|
||||||
|
|
||||||
bool IsInobjectSlackTrackingInProgress() const;
|
bool IsInobjectSlackTrackingInProgress() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -315,6 +323,7 @@ class SharedFunctionInfoRef : public HeapObjectRef {
|
|||||||
|
|
||||||
int internal_formal_parameter_count() const;
|
int internal_formal_parameter_count() const;
|
||||||
bool has_duplicate_parameters() const;
|
bool has_duplicate_parameters() const;
|
||||||
|
int function_map_index() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace compiler
|
} // namespace compiler
|
||||||
|
Loading…
Reference in New Issue
Block a user