[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
|
||||
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(Handle<Map> map,
|
||||
FieldAccess AccessBuilder::ForJSObjectInObjectProperty(const MapRef& map,
|
||||
int index) {
|
||||
int const offset = map->GetInObjectPropertyOffset(index);
|
||||
int const offset = map.GetInObjectPropertyOffset(index);
|
||||
FieldAccess access = {kTaggedBase, offset,
|
||||
MaybeHandle<Name>(), MaybeHandle<Map>(),
|
||||
Type::NonInternal(), MachineType::AnyTagged(),
|
||||
|
@ -48,7 +48,7 @@ class V8_EXPORT_PRIVATE AccessBuilder final
|
||||
static FieldAccess ForJSObjectElements();
|
||||
|
||||
// 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(
|
||||
int offset, WriteBarrierKind write_barrier_kind = kFullWriteBarrier);
|
||||
|
||||
|
@ -1739,8 +1739,9 @@ Reduction JSCallReducer::ReduceArrayFilter(Node* node,
|
||||
ab.Store(AccessBuilder::ForJSArrayLength(packed_kind),
|
||||
jsgraph()->ZeroConstant());
|
||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||
ab.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
||||
jsgraph()->UndefinedConstant());
|
||||
ab.Store(
|
||||
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||
jsgraph()->UndefinedConstant());
|
||||
}
|
||||
a = effect = ab.Finish();
|
||||
}
|
||||
|
@ -150,8 +150,9 @@ Reduction JSCreateLowering::ReduceJSCreate(Node* node) {
|
||||
a.Store(AccessBuilder::ForJSObjectElements(),
|
||||
jsgraph()->EmptyFixedArrayConstant());
|
||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
||||
jsgraph()->UndefinedConstant());
|
||||
a.Store(
|
||||
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||
jsgraph()->UndefinedConstant());
|
||||
}
|
||||
RelaxControls(node);
|
||||
a.FinishAndChange(node);
|
||||
@ -475,8 +476,9 @@ Reduction JSCreateLowering::ReduceJSCreateGeneratorObject(Node* node) {
|
||||
|
||||
// Handle in-object properties, too.
|
||||
for (int i = 0; i < initial_map->GetInObjectProperties(); ++i) {
|
||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(initial_map, i),
|
||||
undefined);
|
||||
a.Store(
|
||||
AccessBuilder::ForJSObjectInObjectProperty(MapRef(initial_map), i),
|
||||
undefined);
|
||||
}
|
||||
a.FinishAndChange(node);
|
||||
return Changed(node);
|
||||
@ -526,7 +528,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
|
||||
a.Store(AccessBuilder::ForJSArrayLength(initial_map->elements_kind()),
|
||||
length);
|
||||
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());
|
||||
}
|
||||
RelaxControls(node);
|
||||
@ -571,7 +573,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node, Node* length,
|
||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
||||
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());
|
||||
}
|
||||
RelaxControls(node);
|
||||
@ -627,7 +629,7 @@ Reduction JSCreateLowering::ReduceNewArray(Node* node,
|
||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||
a.Store(AccessBuilder::ForJSArrayLength(elements_kind), length);
|
||||
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());
|
||||
}
|
||||
RelaxControls(node);
|
||||
@ -970,11 +972,12 @@ Reduction JSCreateLowering::ReduceJSCreateBoundFunction(Node* node) {
|
||||
}
|
||||
|
||||
Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
||||
DisallowHandleDereference disallow_dereference;
|
||||
DCHECK_EQ(IrOpcode::kJSCreateClosure, node->opcode());
|
||||
CreateClosureParameters const& p = CreateClosureParametersOf(node->op());
|
||||
Handle<SharedFunctionInfo> shared = p.shared_info();
|
||||
Handle<FeedbackCell> feedback_cell = p.feedback_cell();
|
||||
Handle<Code> code = p.code();
|
||||
SharedFunctionInfoRef shared(p.shared_info());
|
||||
HeapObjectRef feedback_cell(p.feedback_cell());
|
||||
HeapObjectRef code(p.code());
|
||||
Node* effect = NodeProperties::GetEffectInput(node);
|
||||
Node* control = NodeProperties::GetControlInput(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
|
||||
// seen more than one instantiation, this simplifies the generated code and
|
||||
// also serves as a heuristic of which allocation sites benefit from it.
|
||||
if (feedback_cell->map() !=
|
||||
ReadOnlyRoots(isolate()).many_closures_cell_map()) {
|
||||
// The generic path can only create closures for user functions.
|
||||
DCHECK_EQ(isolate()->builtins()->builtin(Builtins::kCompileLazy), *code);
|
||||
if (!feedback_cell.map(js_heap_broker())
|
||||
.equals(MapRef(factory()->many_closures_cell_map()))) {
|
||||
return NoChange();
|
||||
}
|
||||
|
||||
Handle<Map> function_map(
|
||||
Map::cast(native_context()->get(shared->function_map_index())),
|
||||
isolate());
|
||||
DCHECK(!function_map->IsInobjectSlackTrackingInProgress());
|
||||
DCHECK(!function_map->is_dictionary_map());
|
||||
MapRef function_map = native_context_ref().GetFunctionMapFromIndex(
|
||||
js_heap_broker(), shared.function_map_index());
|
||||
DCHECK(!function_map.IsInobjectSlackTrackingInProgress());
|
||||
DCHECK(!function_map.is_dictionary_map());
|
||||
|
||||
// TODO(turbofan): We should use the pretenure flag from {p} here,
|
||||
// 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.
|
||||
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
||||
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::ForJSObjectPropertiesOrHash(),
|
||||
jsgraph()->EmptyFixedArrayConstant());
|
||||
@ -1020,12 +1020,12 @@ Reduction JSCreateLowering::ReduceJSCreateClosure(Node* node) {
|
||||
a.Store(AccessBuilder::ForJSFunctionFeedbackCell(), feedback_cell);
|
||||
a.Store(AccessBuilder::ForJSFunctionCode(), code);
|
||||
STATIC_ASSERT(JSFunction::kSizeWithoutPrototype == 7 * kPointerSize);
|
||||
if (function_map->has_prototype_slot()) {
|
||||
if (function_map.has_prototype_slot()) {
|
||||
a.Store(AccessBuilder::ForJSFunctionPrototypeOrInitialMap(),
|
||||
jsgraph()->TheHoleConstant());
|
||||
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),
|
||||
jsgraph()->UndefinedConstant());
|
||||
}
|
||||
@ -1209,7 +1209,7 @@ Reduction JSCreateLowering::ReduceJSCreateEmptyLiteralObject(Node* node) {
|
||||
a.Store(AccessBuilder::ForJSObjectPropertiesOrHash(), properties);
|
||||
a.Store(AccessBuilder::ForJSObjectElements(), elements);
|
||||
for (int i = 0; i < map->GetInObjectProperties(); i++) {
|
||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(map, i),
|
||||
a.Store(AccessBuilder::ForJSObjectInObjectProperty(MapRef(map), i),
|
||||
jsgraph()->UndefinedConstant());
|
||||
}
|
||||
|
||||
@ -1712,8 +1712,8 @@ Node* JSCreateLowering::AllocateFastLiteral(Node* effect, Node* control,
|
||||
int const boilerplate_length = boilerplate_map.GetInObjectProperties();
|
||||
for (int index = static_cast<int>(inobject_fields.size());
|
||||
index < boilerplate_length; ++index) {
|
||||
FieldAccess access = AccessBuilder::ForJSObjectInObjectProperty(
|
||||
boilerplate_map.object<Map>(), index);
|
||||
FieldAccess access =
|
||||
AccessBuilder::ForJSObjectInObjectProperty(boilerplate_map, index);
|
||||
Node* value = jsgraph()->HeapConstant(factory()->one_pointer_filler_map());
|
||||
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(); }
|
||||
|
||||
bool ObjectRef::equals(const ObjectRef& other) const {
|
||||
return object<Object>().equals(other.object<Object>());
|
||||
}
|
||||
|
||||
base::Optional<ContextRef> ContextRef::previous(
|
||||
const JSHeapBroker* broker) const {
|
||||
AllowHandleAllocation handle_allocation;
|
||||
@ -411,6 +415,16 @@ bool MapRef::IsFixedCowArrayMap(const JSHeapBroker* broker) const {
|
||||
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 {
|
||||
AllowHandleDereference allow_handle_dereference;
|
||||
return object<JSArray>()->GetElementsKind();
|
||||
@ -483,6 +497,11 @@ int SharedFunctionInfoRef::internal_formal_parameter_count() const {
|
||||
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 {
|
||||
AllowHandleDereference allow_handle_dereference;
|
||||
return object<SharedFunctionInfo>()->has_duplicate_parameters();
|
||||
@ -558,6 +577,14 @@ MapRef NativeContextRef::map_key_value_iterator_map(
|
||||
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 internal
|
||||
} // namespace v8
|
||||
|
@ -100,6 +100,8 @@ class ObjectRef {
|
||||
bool IsSmi() const;
|
||||
int AsSmi() const;
|
||||
|
||||
bool equals(const ObjectRef& other) const;
|
||||
|
||||
#define HEAP_IS_METHOD_DECL(Name) bool Is##Name() const;
|
||||
HEAP_BROKER_KIND_LIST(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_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 {
|
||||
@ -260,10 +264,14 @@ class MapRef : public HeapObjectRef {
|
||||
NameRef GetPropertyKey(const JSHeapBroker* broker, int i) const;
|
||||
FieldIndex GetFieldIndexFor(int i) const;
|
||||
|
||||
int GetInObjectPropertyOffset(int index) const;
|
||||
|
||||
bool IsJSArrayMap() const;
|
||||
bool IsFixedCowArrayMap(const JSHeapBroker* broker) const;
|
||||
bool is_dictionary_map() const;
|
||||
|
||||
bool has_prototype_slot() const;
|
||||
|
||||
bool IsInobjectSlackTrackingInProgress() const;
|
||||
};
|
||||
|
||||
@ -315,6 +323,7 @@ class SharedFunctionInfoRef : public HeapObjectRef {
|
||||
|
||||
int internal_formal_parameter_count() const;
|
||||
bool has_duplicate_parameters() const;
|
||||
int function_map_index() const;
|
||||
};
|
||||
|
||||
} // namespace compiler
|
||||
|
Loading…
Reference in New Issue
Block a user